<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://opensimulator.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://opensimulator.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cmickeyb</id>
		<title>OpenSimulator - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://opensimulator.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cmickeyb"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Special:Contributions/Cmickeyb"/>
		<updated>2026-05-06T09:25:26Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.19.9</generator>

	<entry>
		<id>http://opensimulator.org/wiki/Feature_Proposals/Dispatcher</id>
		<title>Feature Proposals/Dispatcher</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Feature_Proposals/Dispatcher"/>
				<updated>2014-12-21T04:31:43Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Template copies&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Date=&lt;br /&gt;
&lt;br /&gt;
Date of this proposal.&lt;br /&gt;
&lt;br /&gt;
= Status (draft, in progress, done or abandoned) =&lt;br /&gt;
&lt;br /&gt;
Status of the proposal. No set form as of yet, but could be draft/in progress/done/abandoned.&lt;br /&gt;
&lt;br /&gt;
= Proposers =&lt;br /&gt;
&lt;br /&gt;
The names of the people proposing this feature.&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
&lt;br /&gt;
A summary of what this feature is about.&lt;br /&gt;
&lt;br /&gt;
= Proposal =&lt;br /&gt;
&lt;br /&gt;
The text of the proposal.&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Feature_Proposals</id>
		<title>Feature Proposals</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Feature_Proposals"/>
				<updated>2014-12-21T04:31:25Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Present */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Feature Proposals==&lt;br /&gt;
If you want to propose a feature, you should do so on the opensim-dev mailing list. If there is interest or if you plan to write the code yourself, you can create a page here. Please do not propose features in the Mantis bug tracker. Please do not propose features if you don't have a clear idea of how they would work on a technical level. Please do not propose features expecting other people to do the implementation work without convincing them first - this will not happen.&lt;br /&gt;
&lt;br /&gt;
Feature proposals must be created in conjunction with a post to the opensim-dev mailing list - if they are just created here then it's possible they will not get seen by other developers.&lt;br /&gt;
&lt;br /&gt;
If you're adding a proposal here, please do it with a page name of Feature_Proposals/&amp;lt;name of service&amp;gt;. For example Feature_Proposals/AutoBackup.&lt;br /&gt;
&lt;br /&gt;
=== Templates ===&lt;br /&gt;
&lt;br /&gt;
* [[Feature Proposal Template]] - Use this template for your document.&lt;br /&gt;
&lt;br /&gt;
=== Present ===&lt;br /&gt;
&lt;br /&gt;
* [[Feature Proposals/Dispatcher]]&lt;br /&gt;
* [[Feature Proposals/OsGetRegionSize]]&lt;br /&gt;
* [[Feature Proposals/Dynamic Attributes in Scene Objects]]&lt;br /&gt;
* [[Feature Proposals/Deduplicating Asset Service]]&lt;br /&gt;
* [[Feature Proposals/Improve Groups Service]]&lt;br /&gt;
* [[Feature Proposals/BulletSim_OpenCL]]&lt;br /&gt;
* [[IntegrationService]]&lt;br /&gt;
* [[RemoteAdmin:RemoteAdmin_Proposals]] - proposals for additional [[RemoteAdmin]] external methods.&lt;br /&gt;
&lt;br /&gt;
=== Past ===&lt;br /&gt;
&lt;br /&gt;
* [[Feature Proposals/Multi-Region OARs]]&lt;br /&gt;
* [[Feature Proposals/AutoBackup|AutoBackup]]&lt;br /&gt;
* [[Statistics Server]] - Proposal for a statistics server in OpenSimulator.&lt;br /&gt;
* [[OpenID]] - Proposal for using OpenID in OpenSimulator&lt;br /&gt;
* [[AssetServerProposal]] - Proposal for a distributed asset server&lt;br /&gt;
* [[A better SimCrossing]] - A work in progress about implementing a smooth simcrossing&lt;br /&gt;
* [[Creating profiles not used for login]] - RFC for alternative ways of creating profiles that will never be used for login&lt;br /&gt;
* [[OpenSim Profile Anchors]] - a mechanism for retaining creator information for offline item transfers&lt;br /&gt;
* [[Explicit Object Serialization]] - a proposal to explicitly serialize scene objects rather than using automatic .NET XML serialization&lt;br /&gt;
* [[Opensim: 0.5 Release Target Discussion]]&lt;br /&gt;
* [[Opensim: 0.6 Release Target Discussion]]&lt;br /&gt;
* [[Opensim: Future Release Discussion]]&lt;br /&gt;
* [[OpenWiredux: Taking the next step]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Proposal]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:34:17Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
state create&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        // Rez the object &amp;quot;reztest&amp;quot; from the current object's inventory, give it the json&lt;br /&gt;
        // fragment &amp;quot;{ 'start' : 'abc&amp;quot; }&amp;quot; as a start parameter in its object store&lt;br /&gt;
        string sparam = &amp;quot;{ 'start' : 'abc' }&amp;quot;&lt;br /&gt;
        reqID = JsonRezAtRoot(&amp;quot;reztest&amp;quot;, llGetPos() + &amp;lt;0.0, 0.0, 5.0&amp;gt;, ZERO_VECTOR, llGetRot(), sparam);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer result, string objectid, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        if (id == reqID)&lt;br /&gt;
            llOwnerSay(&amp;quot;created object &amp;quot; + msg);&lt;br /&gt;
    }            &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the new object could have use the following code to extract the value from the object store:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default &lt;br /&gt;
{&lt;br /&gt;
    // ---------------------------------------------&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        if (JsonTestStore(llGetKey()))&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;pulling start parameters from object store&amp;quot;);&lt;br /&gt;
            llOwnerSay(&amp;quot;start parameters are &amp;quot; + JsonGetJson(llGetKey(), &amp;quot;.&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
     }&lt;br /&gt;
    &lt;br /&gt;
    // ---------------------------------------------&lt;br /&gt;
    on_rez(integer p)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
* JsonGetNodeType&lt;br /&gt;
* JsonGetValueType&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== int nodetype = JsonGetNodeType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the type of node identified by the specified path. The following node types could be returned: &lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
=== int valuetype = JsonGetValueType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
For nodes in the store that specify values, return the type of value stored. Note that currently only string values can be set or returned through the JsonGetValue and JsonSetValue script functions. However, other values can be specified inside Json fragments in notecards or using the JsonSetJson or JsonGetJson functions.&lt;br /&gt;
&lt;br /&gt;
The following value types could be returned:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:27:14Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
* JsonGetNodeType&lt;br /&gt;
* JsonGetValueType&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== int nodetype = JsonGetNodeType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the type of node identified by the specified path. The following node types could be returned: &lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
=== int valuetype = JsonGetValueType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
For nodes in the store that specify values, return the type of value stored. Note that currently only string values can be set or returned through the JsonGetValue and JsonSetValue script functions. However, other values can be specified inside Json fragments in notecards or using the JsonSetJson or JsonGetJson functions.&lt;br /&gt;
&lt;br /&gt;
The following value types could be returned:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:24:10Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Helper Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
* JsonGetNodeType&lt;br /&gt;
* JsonGetValueType&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== int nodetype = JsonGetNodeType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the type of node identified by the specified path. The following node types could be returned: &lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
=== int valuetype = JsonGetValueType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
For nodes in the store that specify values, return the type of value stored. Note that currently only string values can be set or returned through the JsonGetValue and JsonSetValue script functions. However, other values can be specified inside Json fragments in notecards or using the JsonSetJson or JsonGetJson functions.&lt;br /&gt;
&lt;br /&gt;
The following value types could be returned:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:23:08Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Helper Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
* JsonGetNodeType&lt;br /&gt;
* JsonGetValueType&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== int nodetype = JsonGetNodeType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the type of node identified by the specified path. The following node types could be returned: &lt;br /&gt;
&lt;br /&gt;
=== int valuetype = JsonGetValueType(key storeid, string path) ===&lt;br /&gt;
&lt;br /&gt;
For nodes in the store that specify values, return the type of value stored. Note that currently only string values can be set or returned through the JsonGetValue and JsonSetValue script functions. However, other values can be specified inside Json fragments in notecards or using the JsonSetJson or JsonGetJson functions.&lt;br /&gt;
&lt;br /&gt;
The following value types could be returned:&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:16:24Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* integer status = JsonDestroyStore(key storeID) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:15:46Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetJson(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:14:34Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* string jsonvalue = JsonGetValueJson(key storeID, string path) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetJson(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:12:57Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* integer status = JsonTestStore(key storeID) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists or 0 if it does not. Used to test if a shared store has been created.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:12:26Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* integer status = JsonDestroyStore() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonAttachObjectStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a store is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T03:11:35Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Basic Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module provides functions to interrogate the store to test for node and value types. The following constants are returned by the JsonGetNodeType function:&lt;br /&gt;
&lt;br /&gt;
* JSON_NODETYPE_UNDEF - the node type is unknown or the node does not exist&lt;br /&gt;
* JSON_NODETYPE_OBJECT - the node is a key-accessed dictionary&lt;br /&gt;
* JSON_NODETYPE_ARRAY - the node is an index-accessed array&lt;br /&gt;
* JSON_NODETYPE_VALUE - the node is a value &lt;br /&gt;
&lt;br /&gt;
And the following constants describe the value types of a JSON_NODETYPE_VALUE node:&lt;br /&gt;
&lt;br /&gt;
* JSON_VALUETYPE_UNDEF - the value is unknown or the node is not a value&lt;br /&gt;
* JSON_VALUETYPE_BOOLEAN - the value of the node is a boolean&lt;br /&gt;
* JSON_VALUETYPE_INTEGER - the node has an integer value&lt;br /&gt;
* JSON_VALUETYPE_FLOAT - the node has a float value&lt;br /&gt;
* JSON_VALUEYTYPE_STRING - the node has a string value&lt;br /&gt;
&lt;br /&gt;
Note that all accessors on a JsonStore currently return a string that can be cast to another value type.&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonAttachObjectStore&lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestStore &lt;br /&gt;
*JsonRezAtRoot&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonList2Path&lt;br /&gt;
*JsonGetNodeType/JsonGetValueType&lt;br /&gt;
*JsonGetValue/JsonGetJson &lt;br /&gt;
*JsonSetValue/JsonSetJson&lt;br /&gt;
*JsonRemoveValue &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
*JsonTakeValue/JsonTakeJson&lt;br /&gt;
*JsonReadValue/JsonReadJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore()  ===&lt;br /&gt;
&lt;br /&gt;
Ensure that a JsonStore is associated with the object (create the store if it doesn't already exist). The store identifier will be the same as the object identifier in which the script is running. &lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonTestStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Returns 1 if the identified store exists.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key request = JsonRezAtRoot(string item, vector pos, vector velocity, rotation rot, string param)  ===&lt;br /&gt;
&lt;br /&gt;
This function is very similar to llRezAtRoot except for two differences. The first is that the string &amp;quot;param&amp;quot; is parsed as JSON and placed into a store identified by the newly created objects identifier. The second is that a link_message event is generated for each of the objects created. The integer parameter is the number of objects remaining to be created (for coalesced objects), the string parameter is the identifier of the newly created object, and the key parameter is the request identifier returned by the call to JsonRezAtRoot.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T02:51:54Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* JsonStore Region Module API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public enum JsonStoreNodeType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Object = 1,&lt;br /&gt;
        Array = 2,&lt;br /&gt;
        Value = 3&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public enum JsonStoreValueType&lt;br /&gt;
    {&lt;br /&gt;
        Undefined = 0,&lt;br /&gt;
        Boolean = 1,&lt;br /&gt;
        Integer = 2,&lt;br /&gt;
        Float = 3,&lt;br /&gt;
        String = 4,&lt;br /&gt;
        UUID = 5&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        JsonStoreNodeType GetNodeType(UUID storeID, string path);&lt;br /&gt;
        JsonStoreValueType GetValueType(UUID storeID, string path);&lt;br /&gt;
&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
&lt;br /&gt;
        int GetArrayLength(UUID storeID, string path);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T02:49:19Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* JsonStore Path Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
The function JsonList2Path can be used to convert a list of tokens into a JsonStore path. This is particularly useful if you want to iterate through arrays in the store.&lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
        bool TestPath(UUID storeID, string path, bool useJson);&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T02:46:48Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* General Points */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function. However, stores created by a script will be garbage collected when the script is deleted or reset. This can affect other scripts if they have access to a shared store.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetPathJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
        bool TestPath(UUID storeID, string path, bool useJson);&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2014-02-10T02:44:51Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data.  Please be aware that it is currently experimental and subject to change which may make older scripts fail to work or work slightly differently.&lt;br /&gt;
&lt;br /&gt;
Nodes are currently restricted to array, object and string.  If JSON is added (via JsonCreateStore(), JsonSetJson() or other such methods) that contains raw number values, then these can still be retrieved but only as strings.&lt;br /&gt;
&lt;br /&gt;
= Enabling the Module =&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to access JsonStore via script methods, you will also need to enable permission for MOD functions to run, if you have not done so already:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[XEngine]&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= General Points =&lt;br /&gt;
&lt;br /&gt;
* The module works by allow scripts to create their own stores for JSON data.  JSON can either be written directly, read in from a notecard or added via some other means (such as a separate request to fetch data from an external server).&lt;br /&gt;
&lt;br /&gt;
* Stores are referenced via a key.  This key can be passed to other scripts so that they can share the same store.&lt;br /&gt;
&lt;br /&gt;
* Stores are not persisted.  Once the simulator is reset the data will disappear if other steps aren't taken to store it (such as within notecards).&lt;br /&gt;
&lt;br /&gt;
* If you have finished with a store, you should remove it with the JsonDestroyStore() function.  If this is not done then it will continue to occupy memory until the simulator is reset.&lt;br /&gt;
&lt;br /&gt;
* If you want to see the whole contents of a store via script for debugging purposes, then a good way to do this is to print the serialized JsonStore with the script line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
llOwnerSay(JsonGetValueJson(storeID, &amp;quot;.&amp;quot;));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Path Syntax =&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
== Formal Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// reference the root node, as used in calls such as JsonGetPathJson(storeId, &amp;quot;.&amp;quot;) &lt;br /&gt;
// to serialize the whole store&lt;br /&gt;
&amp;quot;.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an element&lt;br /&gt;
&amp;quot;elem&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item&lt;br /&gt;
&amp;quot;[0]&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.  This is a shortcut for elem.[0]&lt;br /&gt;
&amp;quot;elem[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key.&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// reference an array item where elem is the key and elem itself &lt;br /&gt;
// contains braces {}, brackets [] or periods .&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot; &lt;br /&gt;
// and foo or bar contain elements that need to be delineated.&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
// this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= JsonStore Value Syntax =&lt;br /&gt;
&lt;br /&gt;
= JsonStore Region Module API =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Methods for manipulating the region store are made accessible via the IJsonStore interface in the Interfaces directory of OpenSim.Region.Framework.dll.  These methods are&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    public delegate void TakeValueCallback(string s);&lt;br /&gt;
&lt;br /&gt;
    public interface IJsonStoreModule&lt;br /&gt;
    {&lt;br /&gt;
        bool AttachObjectStore(UUID objectID);&lt;br /&gt;
        bool CreateStore(string value, ref UUID result);&lt;br /&gt;
        bool DestroyStore(UUID storeID);&lt;br /&gt;
        bool TestStore(UUID storeID);&lt;br /&gt;
        bool TestPath(UUID storeID, string path, bool useJson);&lt;br /&gt;
        bool SetValue(UUID storeID, string path, string value, bool useJson);&lt;br /&gt;
        bool RemoveValue(UUID storeID, string path);&lt;br /&gt;
        bool GetValue(UUID storeID, string path, bool useJson, out string value);&lt;br /&gt;
&lt;br /&gt;
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TODO: Documentation on these methods.  At this point, you will need to refer to the comparable script functions below.'''&lt;br /&gt;
&lt;br /&gt;
= JsonStore Script Functions =&lt;br /&gt;
&lt;br /&gt;
== Basic Functions ==&lt;br /&gt;
&lt;br /&gt;
These functions allow you to manipulate stores, set get and test values and read and write JSON to notecards.&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonGetArrayLength&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
// Create a JsonStore initialized with a key 'Hello' point towards the string 'World' &lt;br /&gt;
// and a key 'Event' pointing to an array with two values '1, 2'&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier.  You should call this whenever you're finished with a JsonStore.&lt;br /&gt;
&lt;br /&gt;
(In next release).  Returns 1 if the operation is successful.  Returns 0 if the operation was not successful or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5).  Return 1 if the operation is successful or if the store did not exit.  Returns 0 if the operation was unsuccessful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        integer res = JsonDestroyStore(storeID);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (string)res);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        requestID = JsonWriteNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Notecard written&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
This example presumes that the prim contains the &amp;quot;nc1&amp;quot; notecard saved in the JsonWriteNotecard() example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
key storeID;&lt;br /&gt;
key requestID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {       &lt;br /&gt;
        storeID = JsonCreateStore(&amp;quot;{}&amp;quot;); &lt;br /&gt;
        requestID = JsonReadNotecard(storeID, &amp;quot;&amp;quot;, &amp;quot;nc1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, string sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));       &lt;br /&gt;
&lt;br /&gt;
            JsonDestroyStore(storeID);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string.  If the value exists then it is returned.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
The raw string is returned.  If you want a string token that you could then use with JsonSetValueJson() then you will need to use JsonGetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be Today&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path.  In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.  If the value does not exist or the store does not exist then an empty string is returned.&lt;br /&gt;
&lt;br /&gt;
Please note that if the value is a string (i.e. a leaf-node), then it will be returned as a token surrounded by single quotes (') instead of as a raw string.  This can then be used in JsonSetValueJson().&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : 'Today' } }&amp;quot;);&lt;br /&gt;
        string res = JsonGetValue(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + res); // res will be 'Today' (note the single quotes in the string itself).&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValue(key storeID, string path, string value) ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;, &amp;quot;Apple&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Pancake.Banana&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonSetValueJson(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
'''From git master commit 61f18d1 (Fri Feb 15 00:38:07 2013), post OpenSimulator 0.7.5, this will become JsonGetJson()'''&lt;br /&gt;
&lt;br /&gt;
Save the JSON at the location identified by the path in the store. Any data currently at the location will be replaced.  The value given must be a JSON encoded string.  If you want to specify a string leaf-node, then this must be surrounded by single quotes (').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World'&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonSetValue(storeID, &amp;quot;Hello.World&amp;quot;, &amp;quot;'Apple'&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Hello.World&amp;quot;); // returns Apple&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        intRes = JsonSetValue(storeID, &amp;quot;.&amp;quot;, &amp;quot;{'Event' : ['1', '2']}&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Set result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        string stringRes = JsonGetValue(storeID, &amp;quot;Event[0]&amp;quot;); // returns 1&lt;br /&gt;
        llOwnerSay(&amp;quot;Get result &amp;quot; + stringRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.  &lt;br /&gt;
&lt;br /&gt;
(In OpenSimulator 0.7.5). Returns 1 if the value was removed or the value did not exist.  Returns 0 if the store does not exist.&lt;br /&gt;
&lt;br /&gt;
(In next release). Returns 1 if value was removed.  Returns 0 if the path does not exist or the store does not exist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : 'World', 'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer intRes = JsonRemoveValue(storeID, &amp;quot;Hello&amp;quot;);   &lt;br /&gt;
        llOwnerSay(&amp;quot;Remove result &amp;quot; + (string)intRes);&lt;br /&gt;
        &lt;br /&gt;
        intRes = JsonTestPath(storeID, &amp;quot;Hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;TestPath result &amp;quot; + (string)intRes);&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer res = JsonGetArrayLength(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
'''Current development code only (will be released in OpenSimulator 0.7.6).  &lt;br /&gt;
&lt;br /&gt;
Get the length of the array at the given path.  Returns -1 if &lt;br /&gt;
&lt;br /&gt;
* The path does not exist&lt;br /&gt;
* The node at the path is not an array &lt;br /&gt;
* The JsonStore for the storeID does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : { 'World' : ['1', '2'] } }&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer res= JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Result &amp;quot; + (integer)res);  // should be 2&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Helper Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions to help with manipulating JSON or using the store.&lt;br /&gt;
&lt;br /&gt;
Currently there is only one helper function&lt;br /&gt;
&lt;br /&gt;
* JsonList2Path&lt;br /&gt;
&lt;br /&gt;
=== string path = JsonList2Path(list components) ===&lt;br /&gt;
&lt;br /&gt;
Convert the given list of components to a path.  Components can be strings or integers.  Strings are used as ordinary path name components.  Integers are used as index components to arrays.&lt;br /&gt;
&lt;br /&gt;
This method exists chiefly to make it easier to iterate through arrays.  For example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        key storeID = JsonCreateStore(&amp;quot;{'Hello' : {'World' : [{'name' : 'pete'}, {'name' : 'tom'}, {'name' : 'wilma'}]}}&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        string path;&lt;br /&gt;
        string name;&lt;br /&gt;
        for (i = 0; i &amp;lt; JsonGetArrayLength(storeID, &amp;quot;Hello.World&amp;quot;); i++)&lt;br /&gt;
        {&lt;br /&gt;
            path = JsonList2Path([&amp;quot;Hello.World&amp;quot;, i, &amp;quot;name&amp;quot;]);           &lt;br /&gt;
            name = JsonGetValue(storeID, path);&lt;br /&gt;
            llOwnerSay(path + &amp;quot; is '&amp;quot; + name + &amp;quot;'&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        JsonDestroyStore(storeID);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Functions ==&lt;br /&gt;
&lt;br /&gt;
These are functions that allow scripts to receive notifications of values when they become available.  This is useful for signalling between scripts or between scripts and region modules.&lt;br /&gt;
&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key requestID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
= Examples =&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Appearance_Troubleshooting</id>
		<title>Appearance Troubleshooting</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Appearance_Troubleshooting"/>
				<updated>2013-04-22T19:58:03Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Establishing avatar appearance on login */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
Avatar appearance is a particularly complex issue in current OpenSimulator since it involves a complex interaction between a user's viewer (where the texture is actually created) and the simulator (which needs to send appearance information to the viewer, receive the baked textures and distribute those to other viewers).  Moreover, the exact steps of this interaction vary depending on whether the user is freshly logging in or region crossing/teleporting to another region on the same or a different simulator.&lt;br /&gt;
&lt;br /&gt;
This document currently describes only the classic viewer-side texture baking.  Server-side baking would do most if not all of these steps (especially the baking itself) in OpenSimulator instead.  However, this is not yet implemented by OpenSimulator.&lt;br /&gt;
&lt;br /&gt;
= Steps =&lt;br /&gt;
&lt;br /&gt;
== Establishing avatar appearance on login ==&lt;br /&gt;
&lt;br /&gt;
Making an avatar appearance available in a simulator on login currently involves a large number of steps.  &lt;br /&gt;
&lt;br /&gt;
# On login, the viewer asks the simulator what body parts and clothing it is wearing (AgentWearablesRequest UDP packet)&lt;br /&gt;
# The simulator replies (AgentWearablesUpdate UDP packet).&lt;br /&gt;
# The viewer confirms some appearance information to the server (AgentSetAppearance UDP packets).  This includes visual parameters (nose length, etc.).&lt;br /&gt;
# The viewer asks the simulator if its appearance is already cached (AgentCachedTexture UDP packet).&lt;br /&gt;
# The simulator currently always responds that no data is cached (AgentCachedTextureResponse UDP packet).&lt;br /&gt;
# The viewer sends further appearance information the server detailing the baked texture UUIDs it is about to upload (AgentSetAppearance UDP packets).&lt;br /&gt;
# The viewer creates the appearance textures from the wearables (bakes them).&lt;br /&gt;
# The viewer uploads these new baked textures to the simulator via the UploadBakedTexture HTTP capability.&lt;br /&gt;
# The simulator stores this asset data in the simulator cache but does not send it to the asset service.&lt;br /&gt;
# The simulator tells other viewers that can see that avatar (either because they are in the same region or neighbouring regions) about the UUIDs of the baked textures uploaded for that avatar (AvatarAppearance UDP packets).&lt;br /&gt;
# These other viewers then request the baked textures for these UUIDs.&lt;br /&gt;
# When a viewer has received all the baked textures for such an avatar, then it is displayed instead of remaining as a cloud.&lt;br /&gt;
&amp;lt;!-- Commented out since this is never true on login.  Will reuse this text when we write the region cross/teleport section --&amp;gt;&lt;br /&gt;
&amp;lt;!-- # If the viewer does not already have the baked texture asset, it requests it from the simulator via the GetTexture HTTP capability. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can imagine there are many points at which this process can go wrong on, in the simulator, the sending viewer, the receiving viewer and at the network in between.  If it does go wrong, you will often end up with a gas cloud instead of an avatar.  The text below lists the various ways in which avatar appearance can go wrong, diagnosis commands and some suggestions for trying to fix the situation.&lt;br /&gt;
&lt;br /&gt;
NOTE: The PersistBakeTextures flag in the Appearance section of the ini file allows you to persist baked textures among simulators and over login sessions. On establishment of a scene presence (through login or teleport) the simulator checks the asset service for copies of the baked textures and sends that information to the viewer. On login, this means that textures are not rebaked. While this behavior can lead to a large number of baked textures in the asset service, the only time textures will be re-baked is when 1) the user explicit requests it, 2) the set of wearables changes, or 3) the connection to the asset service is broken. There are some timing issues that come into play as well, though these will simply trigger an unnecessary rebake.&lt;br /&gt;
&lt;br /&gt;
== Establishing avatar appearance on teleport/region cross to another region on the same simulator ==&lt;br /&gt;
&lt;br /&gt;
In this case, the baked textures are already in the simulator's asset cache.  Hence, the steps are&lt;br /&gt;
&lt;br /&gt;
# The simulator tells both the uploading viewer and the other viewers that can see that avatar (either because they are in the same region or neighbouring regions) about the UUIDs of the baked textures it already has for that avatar.&lt;br /&gt;
# These other viewers then request the baked textures for these UUIDs if they don't already have them cached.&lt;br /&gt;
# When a viewer has received all the baked textures for such an avatar, then it is displayed instead of remaining as a cloud.&lt;br /&gt;
&lt;br /&gt;
== Establishing avatar appearance on region cross to another region on a different simulator ==&lt;br /&gt;
'''Todo: Need to fill out this section.  This should be the same as for teleport, but in current git master (as of 2012-02-21) there may be an issue where the avatar does not send AgentSetAppearance on entering the new region, which means that the rebake request is never triggered.'''&lt;br /&gt;
&lt;br /&gt;
== Establishing avatar appearance on teleport to another region on a different simulator ==&lt;br /&gt;
# On completing the teleport, the viewer sends an visual parameters and the UUIDs of the baked textures it previously uploaded to the server (via the AgentSetAppearance UDP packet).&lt;br /&gt;
# Because these textures are not in the asset service (see earlier), OpenSimulator sends a rebake request for each texture (RebakeAvatarTextures UDP packet).&lt;br /&gt;
# The simulator tells other viewers that can see that avatar (either because they are in the same region or neighbouring regions) about the UUIDs of the baked textures uploaded for that avatar (AvatarAppearance UDP packets).&lt;br /&gt;
# These other viewers then request the baked textures for these UUIDs.&lt;br /&gt;
# When a viewer has received all the baked textures for such an avatar, then it is displayed instead of remaining as a cloud.&lt;br /&gt;
&lt;br /&gt;
= Useful commands =&lt;br /&gt;
&lt;br /&gt;
These commands are in OpenSimulator 0.7.4 and later and some will be in 0.7.3.1 and 0.7.3.&lt;br /&gt;
&lt;br /&gt;
== appearance show ==&lt;br /&gt;
&lt;br /&gt;
Usage&lt;br /&gt;
&lt;br /&gt;
 appearance show [&amp;lt;first-name&amp;gt; &amp;lt;last-name&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
 appearance show Lord Lucan&lt;br /&gt;
&lt;br /&gt;
This will show the asset UUID for each baked texture uploaded by the viewer for that user.  For instance, a properly baked user may have something like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
(test one)# appearance show Lord Lucan&lt;br /&gt;
For Lord Lucan in test one&lt;br /&gt;
Bake Type  UUID&lt;br /&gt;
Head       fd783d4a-b1d2-4bdc-89c7-88578b429ccc (uploaded)&lt;br /&gt;
UpperBody  d147b1f5-b99d-49d4-8492-6cd4c7da905e (uploaded)&lt;br /&gt;
LowerBody  e8aae819-e04b-4894-983a-15bd2d354b71 (uploaded)&lt;br /&gt;
Eyes       ae8fe60d-9d20-440d-989a-869d2ee1ed3d (uploaded)&lt;br /&gt;
Skirt      not set&lt;br /&gt;
Hair       4e354649-f880-4204-987a-8d744f531469 (uploaded)&lt;br /&gt;
Lord Lucan baked appearance texture is OK&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The textures may be listed as (not found) if they have been uploaded by the viewer but can't be found in the asset cache.  Or they may be listed as (not set) if the viewer has never uploaded this data.&lt;br /&gt;
&lt;br /&gt;
If no name is given then summary data for all users is displayed.&lt;br /&gt;
&lt;br /&gt;
== appearance send ==&lt;br /&gt;
&lt;br /&gt;
Usage&lt;br /&gt;
 &lt;br /&gt;
 appearance send [&amp;lt;first-name&amp;gt; &amp;lt;last-name&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
e.g. &lt;br /&gt;
&lt;br /&gt;
 appearance send Lord Lucan&lt;br /&gt;
&lt;br /&gt;
Send appearance baked texture IDs to other avatars in the scene.  In theory, this should trigger other avatars to request those textures if they need them.  This will have no effect if the original viewer never uploaded the texture IDs in the first place (i.e. if avatars are appearing as clouds).  If avatars are grey instead, then this command may help.  There is also a ResendAppearanceUpdates config which can periodically resend this data.  We will discuss this later on.&lt;br /&gt;
&lt;br /&gt;
If no name is given then all avatars resend their appearance texture UUIDs to all other avatars.&lt;br /&gt;
&lt;br /&gt;
== appearance rebake ==&lt;br /&gt;
&lt;br /&gt;
Usage&lt;br /&gt;
&lt;br /&gt;
 appearance rebake &amp;lt;first-name&amp;gt; &amp;lt;last-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 &lt;br /&gt;
 appearance rebake Lord Lucan&lt;br /&gt;
&lt;br /&gt;
Now, this sounds like it should be an enormously useful command.  Unfortunately, it will only have any effect if the viewer has already successfully uploaded some baked texture data, even if that turned out to be corrupt.  The viewer will very probably ignore any requests to rebake textures if it has not managed to perform an initial successful bake.&lt;br /&gt;
&lt;br /&gt;
== j2k decode ==&lt;br /&gt;
&lt;br /&gt;
Usage&lt;br /&gt;
&lt;br /&gt;
 j2k decode &amp;lt;id&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 &lt;br /&gt;
 j2k decode ae8fe60d-9d20-440d-989a-869d2ee1ed3d&lt;br /&gt;
&lt;br /&gt;
Attempt a JPEG2000 decode of the given asset.  All baked textures are JPEG2000 files, so this can be useful to assess whether a given upload is corrupt or not.  If the decode succeeds then it will tell you how many the number of layers and components in the JPEG2000 texture.&lt;br /&gt;
&lt;br /&gt;
== dump asset ==&lt;br /&gt;
&lt;br /&gt;
Usage &lt;br /&gt;
 &lt;br /&gt;
 dump asset &amp;lt;id&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
 dump asset ae8fe60d-9d20-440d-989a-869d2ee1ed3d&lt;br /&gt;
&lt;br /&gt;
Dumps an asset to a file with the same name as the ID given.  Can be useful for taking a closer look at textures in an external program (e.g. jiv on Linux) if they have been apparently successfully uploaded.&lt;br /&gt;
&lt;br /&gt;
= Problems and resolutions =&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
* In all these situations, one can force the client to attempt a rebake using the ctrl+alt+r key combination.  This is always worth trying.&lt;br /&gt;
* Remember, it's possible that the viewer has successfully baked but for some reason the upload of the textures to the simulator has failed, or the simulator has failed to redistribute them to other viewers.  In this case, a viewer rebake may work.&lt;br /&gt;
* Another general tip is to try clearing the viewer cache and logging back in.&lt;br /&gt;
* One should also try a different viewer, either an old viewer such as Imprudence or a newer viewer such as Kokua or Firestorm.  Different viewers may have different ways of baking textures or may have issues with bugs.&lt;br /&gt;
* If possible, one should also try a different simulator.  Even if simulators are running exactly the same version of OpenSimulator, they can be running on a different software stack (e.g. Mono rather than Windows .NET) or different hardware.  There may be differences in behaviour that stem from this.&lt;br /&gt;
* Try a quiet region.  Regions with a lot of avatars and objects may be dealing with a lot of traffic that may cause appearance issues.  To test this, you could go to a quieter region or ideally even a local installation of OpenSimulator.&lt;br /&gt;
* If you use the same name in the same viewer for multiple different grids, try using a different installation of the viewer instead.  On some viewers, it may be possible to get confused between different inventories on different grids where the avatar has the same name.  This is especially true in the case of viewers which were not explicitly written to access different grids (though historically the Linden viewer seems to have been okay in this respect).&lt;br /&gt;
&lt;br /&gt;
'''This is probably only a small selection of issues.  Please add more as you encounter them if you know of workarounds or fixes.'''&lt;br /&gt;
&lt;br /&gt;
== Cloudy avatars ==&lt;br /&gt;
&lt;br /&gt;
=== The avatar does not have sufficient clothing or body-parts to bake textures ===&lt;br /&gt;
&lt;br /&gt;
There is a minimum set of body parts and clothing a viewer requires to bake an appearance texture.  There are the shape, hair, skin and eyes body parts, and the shirt and trousers clothing.  Without these, the viewer will never attempt to bake a texture.&lt;br /&gt;
&lt;br /&gt;
==== Solution ====&lt;br /&gt;
&lt;br /&gt;
Make sure your avatar has this minimum set of body parts and clothing.&lt;br /&gt;
&lt;br /&gt;
=== One of the assets for a bodypart/clothing is corrupt or missing ===&lt;br /&gt;
&lt;br /&gt;
Sometimes the necessary data to perform the bake may be corrupt or missing.&lt;br /&gt;
&lt;br /&gt;
==== Solution ====&lt;br /&gt;
&lt;br /&gt;
Try switching to a different set of clothing and body parts (e.g. using the &amp;quot;replace outfit&amp;quot; option), or create the minimum set from scratch and see if wearing these helps.&lt;br /&gt;
&lt;br /&gt;
=== The required clothing or bodypart inventory has not downloaded ===&lt;br /&gt;
&lt;br /&gt;
Sometimes the required clothing or bodypart items for your appearance may not have downloaded, especially on a busy sim where you have a very large inventory and a viewer that aggressively requests inventory data.&lt;br /&gt;
&lt;br /&gt;
==== Solutions ====&lt;br /&gt;
&lt;br /&gt;
* Try a quieter region.  As above, these have less traffic that may crowd out your appearance information (this is a diagnostic test rather than a long term solution).  &lt;br /&gt;
* You may also want to try a viewer which is less aggressive about downloading all inventory information on login.&lt;br /&gt;
* Try turning off or on HTTP inventory if your viewer supports this option.  Newer viewers (version 2, 3 and associated third party viewers) download inventory information using HTTP inventory capabilities rather than via UDP.  In principle, this should result in a much better experience since large inventories do not crowd out other UDP messages (avatar movement, object updates, etc.).  However, it may be worth changing this setting to see if it helps.&lt;br /&gt;
&lt;br /&gt;
=== The viewer graphics code is failing to successfully bake textures ===&lt;br /&gt;
&lt;br /&gt;
We've seen some graphics drivers fail to successfully bake textures.  Sometimes this depends on where the baking is done (e.g. if the viewer is on a second screen).&lt;br /&gt;
&lt;br /&gt;
==== Solution ====&lt;br /&gt;
&lt;br /&gt;
Update your graphics drivers.  Attempt a bake with a simple set of body parts/clothing and on your main screen.&lt;br /&gt;
&lt;br /&gt;
=== An external OpenSimulator configuration system is not fully creating the necessary bodypart/clothing entries ===&lt;br /&gt;
&lt;br /&gt;
This can be a problem with older configuration systems which are not viewer 2 aware, where it was enough to create inventory and avatar entries but item links in the &amp;quot;Current Outfit&amp;quot; folder are necessary.  One would only expect to see this with initial avatar setup.&lt;br /&gt;
&lt;br /&gt;
==== Solution ====&lt;br /&gt;
&lt;br /&gt;
Try an avatar created using the &amp;quot;create user&amp;quot; ROBUST or simulator console command (if running in standalone mode).  On OpenSimulator 0.7.4 this will by default create the minimum clothing and inventory links to display an avatar.  On OpenSimulator 0.7.3.1 you will need to set CreateDefaultAvatarEntries = true in the [UserAccountService] section of Robust.ini or Robust.HG.ini (it is still set true by default on standalone).&lt;br /&gt;
&lt;br /&gt;
== Grey avatars ==&lt;br /&gt;
&lt;br /&gt;
Sometimes avatars may appear grey rather than cloudy.&lt;br /&gt;
&lt;br /&gt;
=== The message containing appearance information has been lost ===&lt;br /&gt;
&lt;br /&gt;
For some reason, the packet containing appearance information is sometimes ignored by the viewer.  The &amp;quot;appearance send&amp;quot; command above may help diagnose this.&lt;br /&gt;
&lt;br /&gt;
==== Solution ====&lt;br /&gt;
&lt;br /&gt;
Try setting ResendAppearanceUpdates = true setting in the [Appearance] section of OpenSim.ini.  This will resend appearance data every 60 seconds.  This will probably not help if avatars are clouds, since this usually signals a failure to upload the data in the first place.&lt;br /&gt;
&lt;br /&gt;
In OpenSimulator 0.7.4 this setting is not on by default (it is not present in OpenSimulator 0.7.3.1 and before).  In OpenSimulator 0.7.5 it will be on by default.&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2013-01-30T17:31:06Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
=== Formal Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;elem&amp;quot;&lt;br /&gt;
&amp;quot;[0]&amp;quot;&lt;br /&gt;
&amp;quot;elem[0]&amp;quot;&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot;&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; // this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot;&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot; // this is a four token path: [{foo}, {bar}, [0], {goof}]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
    // Create a JsonStore initialized with a key pointing to an array with two values&lt;br /&gt;
    storeID = JsonCreateStore(&amp;quot;{'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonReadNotecard(storeID,&amp;quot;Event[0]&amp;quot;,notecardID);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2013-01-30T17:28:09Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* JsonStore Path Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
A JsonStore path is a '.' separated string of tokens that reference elements of the Json store. Path tokens are either strings (for structure access) or array references. The '+' token refers to the end of the array and is used to append values to an array. Strings are quoted with &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot; characters. Array references are quoted with &amp;quot;[&amp;quot; and &amp;quot;]&amp;quot;. When there is no ambiguity, the '.' separator can be dropped.  &lt;br /&gt;
&lt;br /&gt;
=== Formal Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path --&amp;gt; Token | Path '.' Token&lt;br /&gt;
Token --&amp;gt; '[' Index ']' | '{' Identifier '}' | SimpleIdentifier&lt;br /&gt;
Index --&amp;gt; '+' | [0-9]+&lt;br /&gt;
Identifier --&amp;gt; [^}]+&lt;br /&gt;
SimpleIdentifier --&amp;gt; [a-zA-Z]+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;elem&amp;quot;&lt;br /&gt;
&amp;quot;[0]&amp;quot;&lt;br /&gt;
&amp;quot;elem[0]&amp;quot;&lt;br /&gt;
&amp;quot;elem.[0]&amp;quot;&lt;br /&gt;
&amp;quot;{elem}.[0]&amp;quot;&lt;br /&gt;
&amp;quot;{foo.bar}.[0]&amp;quot; -- this is a two token path with the identifier &amp;quot;foo.bar&amp;quot; and array reference &amp;quot;0&amp;quot;&lt;br /&gt;
&amp;quot;{foo}.{bar}.[0]&amp;quot;&lt;br /&gt;
&amp;quot;foo.bar[0].goof&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
    // Create a JsonStore initialized with a key pointing to an array with two values&lt;br /&gt;
    storeID = JsonCreateStore(&amp;quot;{'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonReadNotecard(storeID,&amp;quot;Event[0]&amp;quot;,notecardID);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-08-06T16:24:54Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Adding constants example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Sockets;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenMetaverse;&lt;br /&gt;
using OpenMetaverse.StructuredData;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private static readonly ILog m_log =&lt;br /&gt;
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;
&lt;br /&gt;
        private IConfig m_config = null;&lt;br /&gt;
        private bool m_enabled = true;&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        &lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] start configuration&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            try &lt;br /&gt;
            {&lt;br /&gt;
                if ((m_config = config.Configs[&amp;quot;ModInvoke&amp;quot;]) != null)&lt;br /&gt;
                    m_enabled = m_config.GetBoolean(&amp;quot;Enabled&amp;quot;, m_enabled);&lt;br /&gt;
            }&lt;br /&gt;
            catch (Exception e)&lt;br /&gt;
            {&lt;br /&gt;
                m_log.ErrorFormat(&amp;quot;[ModInvoke] initialization error: {0}&amp;quot;,e.Message);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            m_log.ErrorFormat(&amp;quot;[ModInvoke] module {0} enabled&amp;quot;,(m_enabled ? &amp;quot;is&amp;quot; : &amp;quot;is not&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void PostInitialise()&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Close() { }&lt;br /&gt;
        public void AddRegion(Scene scene) { }&lt;br /&gt;
        public void RemoveRegion(Scene scene)  { }&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled)&lt;br /&gt;
            {&lt;br /&gt;
                m_scene = scene;&lt;br /&gt;
                m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
                if (m_comms == null)&lt;br /&gt;
                {&lt;br /&gt;
                    m_log.WarnFormat(&amp;quot;[ModInvoke] ScriptModuleComms interface not defined&amp;quot;);&lt;br /&gt;
                    m_enabled = false;&lt;br /&gt;
&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest0&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest1&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest2&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest3&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest4&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest5&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest6&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest7&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest8&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
                // Register some constants as well&lt;br /&gt;
                m_comms.RegisterConstant(&amp;quot;ModConstantInt1&amp;quot;,25);&lt;br /&gt;
                m_comms.RegisterConstant(&amp;quot;ModConstantFloat1&amp;quot;,25.000f);&lt;br /&gt;
                m_comms.RegisterConstant(&amp;quot;ModConstantString1&amp;quot;,&amp;quot;abcdefg&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        public string ModTest0(UUID hostID, UUID scriptID)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest0 parameter&amp;quot;);&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public string ModTest1(UUID hostID, UUID scriptID, string value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest1 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int ModTest2(UUID hostID, UUID scriptID, int value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest2 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public float ModTest3(UUID hostID, UUID scriptID, float value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest3 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public UUID ModTest4(UUID hostID, UUID scriptID, UUID value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest4 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Vector3 ModTest5(UUID hostID, UUID scriptID, OpenMetaverse.Vector3 value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest5 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Quaternion ModTest6(UUID hostID, UUID scriptID, OpenMetaverse.Quaternion value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest6 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest7(UUID hostID, UUID scriptID, int count, string val)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[count];&lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
                result[i] = val;&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest8(UUID hostID, UUID scriptID, object[] lparm)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[lparm.Length];&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)&lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
One thing to note regarding parameter and return types: the LSL_Types are not available in the region module; however, all of the OpenMetaverse types are. Use UUID for a key and string, int, OpenMetaverse.Vector3, etc for other types.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-07-17T16:13:43Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Sockets;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenMetaverse;&lt;br /&gt;
using OpenMetaverse.StructuredData;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private static readonly ILog m_log =&lt;br /&gt;
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;
&lt;br /&gt;
        private IConfig m_config = null;&lt;br /&gt;
        private bool m_enabled = true;&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        &lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] start configuration&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            try &lt;br /&gt;
            {&lt;br /&gt;
                if ((m_config = config.Configs[&amp;quot;ModInvoke&amp;quot;]) != null)&lt;br /&gt;
                    m_enabled = m_config.GetBoolean(&amp;quot;Enabled&amp;quot;, m_enabled);&lt;br /&gt;
            }&lt;br /&gt;
            catch (Exception e)&lt;br /&gt;
            {&lt;br /&gt;
                m_log.ErrorFormat(&amp;quot;[ModInvoke] initialization error: {0}&amp;quot;,e.Message);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            m_log.ErrorFormat(&amp;quot;[ModInvoke] module {0} enabled&amp;quot;,(m_enabled ? &amp;quot;is&amp;quot; : &amp;quot;is not&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void PostInitialise()&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Close() { }&lt;br /&gt;
        public void AddRegion(Scene scene) { }&lt;br /&gt;
        public void RemoveRegion(Scene scene)  { }&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled)&lt;br /&gt;
            {&lt;br /&gt;
                m_scene = scene;&lt;br /&gt;
                m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
                if (m_comms == null)&lt;br /&gt;
                {&lt;br /&gt;
                    m_log.WarnFormat(&amp;quot;[ModInvoke] ScriptModuleComms interface not defined&amp;quot;);&lt;br /&gt;
                    m_enabled = false;&lt;br /&gt;
&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest0&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest1&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest2&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest3&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest4&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest5&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest6&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest7&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest8&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        public string ModTest0(UUID hostID, UUID scriptID)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest0 parameter&amp;quot;);&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public string ModTest1(UUID hostID, UUID scriptID, string value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest1 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int ModTest2(UUID hostID, UUID scriptID, int value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest2 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public float ModTest3(UUID hostID, UUID scriptID, float value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest3 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public UUID ModTest4(UUID hostID, UUID scriptID, UUID value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest4 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Vector3 ModTest5(UUID hostID, UUID scriptID, OpenMetaverse.Vector3 value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest5 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Quaternion ModTest6(UUID hostID, UUID scriptID, OpenMetaverse.Quaternion value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest6 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest7(UUID hostID, UUID scriptID, int count, string val)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[count];&lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
                result[i] = val;&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest8(UUID hostID, UUID scriptID, object[] lparm)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[lparm.Length];&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)&lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
One thing to note regarding parameter and return types: the LSL_Types are not available in the region module; however, all of the OpenMetaverse types are. Use UUID for a key and string, int, OpenMetaverse.Vector3, etc for other types.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:43:54Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
    // Create a JsonStore initialized with a key pointing to an array with two values&lt;br /&gt;
    storeID = JsonCreateStore(&amp;quot;{'Event' : ['1', '2']}&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonReadNotecard(storeID,&amp;quot;Event[0]&amp;quot;,notecardID);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
            llOwnerSay(&amp;quot;notecard read: &amp;quot; + JsonGetValueJson(storeID,&amp;quot;Event[0]&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        key requestID = JsonTakeValue(storeID,&amp;quot;Event.Lock&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender, integer ival, integer sval, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1) return;&lt;br /&gt;
        if (id == requestID)&lt;br /&gt;
        {&lt;br /&gt;
            // we now have a &amp;quot;lock&amp;quot;&lt;br /&gt;
            llOwnerSay(&amp;quot;read: &amp;quot; + sval);&lt;br /&gt;
&lt;br /&gt;
            // release the &amp;quot;lock&amp;quot; by placing the value back in the store&lt;br /&gt;
            llSetValue(storeID,&amp;quot;Event.Lock&amp;quot;,sval);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:26:23Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* key requestID = JsonReadValue(key storeID, string path)key reqeustID = JsonReadValueJson(key storeID, string path) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:25:57Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* key requestID = JsonReadValue(key storeID, string path)key reqeustID = JsonReadValueJson(key storeID, string path) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;  ===&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:25:45Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* int status = JsonTestPath(key storeID, string path)int JsonTestPathJson(key storeID, string path) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int status = JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:25:22Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
Add the following to your OpenSim.ini to enable the JsonStore module: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax  ==&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore &lt;br /&gt;
*JsonDestroyStore &lt;br /&gt;
*JsonReadNotecard &lt;br /&gt;
*JsonWriteNotecard &lt;br /&gt;
*JsonTestPath/JsonTestPathJson &lt;br /&gt;
*JsonGetValue/JsonGetValueJson &lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson &lt;br /&gt;
*JsonReadValue/JsonReadValueJson &lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned. &lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int JsonTestPathJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value. &lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Return the value identified by the path. In the case of JsonGetValue() the value must be a string. In the case of JsonGetValueJson() the value will be Json encoded string, array or dictionary.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be removed from the store and returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonTakeValue() will request a string value. JsonTakeValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
This function is used to wait for a value to be available and then return. Since the operation of read and remove is atomic, it can be used to implement locks, task queues and other synchronization primitives.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the path be returned to the script when it is available. The value will be returned through a link_message event with the requestID. JsonReadValue() will request a string value. JsonReadValueJson() will request a Json encoded string that corresponds to a string, array or hash value.&lt;br /&gt;
&lt;br /&gt;
Unlike the JsonTakeValue() operation, the JsonReadValue operation does not remove the value from the store once it becomes available. &lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue)  ===&lt;br /&gt;
&lt;br /&gt;
Save the value at the location identified by the path in the store. Any value currently at the location will be replaced. JsonSetValue() assumes that the value is a string. JsonSetValueJson() assumes that the value is a Json encoded string.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path)  ===&lt;br /&gt;
&lt;br /&gt;
Remove from the store the value identified by the path.&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL Script Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/JsonStore_Module</id>
		<title>JsonStore Module</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/JsonStore_Module"/>
				<updated>2012-04-17T23:06:49Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Created page with &amp;quot;== Introduction  ==  The JsonStore module enables scripts and region modules to share structured data among themselves.   == Enabling the Module  ==    == JsonStore Path Syntax =...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction  ==&lt;br /&gt;
&lt;br /&gt;
The JsonStore module enables scripts and region modules to share structured data among themselves. &lt;br /&gt;
&lt;br /&gt;
== Enabling the Module  ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== JsonStore Path Syntax ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== JsonStore Value Syntax ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== JsonStore Script Functions  ==&lt;br /&gt;
&lt;br /&gt;
*JsonCreateStore&lt;br /&gt;
*JsonDestroyStore&lt;br /&gt;
*JsonReadNotecard&lt;br /&gt;
*JsonWriteNotecard&lt;br /&gt;
*JsonTestPath/JsonTestPathJson&lt;br /&gt;
*JsonGetValue/JsonGetValueJson&lt;br /&gt;
*JsonTakeValue/JsonTakeValueJson&lt;br /&gt;
*JsonReadValue/JsonReadValueJson&lt;br /&gt;
*JsonSetValue/JsonSetValueJson&lt;br /&gt;
&lt;br /&gt;
=== key storeID = JsonCreateStore(string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
Create a JsonStore and initialize it using the Json encoded value. The new store identifier is returned.&lt;br /&gt;
&lt;br /&gt;
=== integer status = JsonDestroyStore(key storeID)  ===&lt;br /&gt;
&lt;br /&gt;
Destroy the JsonStore associated with the provided identifier. Return 1 if the operation is successful.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadNotecard(key storeID, string path, key assetID) ===&lt;br /&gt;
&lt;br /&gt;
Request that the Json encoded content of a notecard be decoded and &amp;amp;nbsp;placed in the structure in the store at the given path. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonWriteNotecard(key storeID, string path, string notecard) ===&lt;br /&gt;
&lt;br /&gt;
Request that the value identified by the given path be Json encoded and written to the notecard. The function returns the request identifier. When the operation completes, a link_message event is generated with the request identifier.&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonTestPath(key storeID, string path)&amp;lt;br&amp;gt;int JsonTestPathJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
Check to see if there is a value identified by the path. In the case of JsonTestPath() the value must be a string. In the case of JsonTestPathJson() the value can be a string, an array, or a dictionary. The function returns 1 when there is an appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== string value = JsonGetValue(key storeID, string path)&amp;lt;br&amp;gt;string jsonvalue = JsonGetValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonTakeValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonTakeValueJson(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== key requestID = JsonReadValue(key storeID, string path)&amp;lt;br&amp;gt;key reqeustID = JsonReadValueJson(key storeID, string path)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonSetValue(key storeID, string path, string value)&amp;lt;br&amp;gt;int status = JsonSetValue(key storeID, string path, string jsonvalue) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== int status = JsonRemoveValue(key storeID, string path) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Examples  ==&lt;br /&gt;
&lt;br /&gt;
*[[OSSL_Script_Library/JsonStore|Generator/Consumer]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/User_Documentation</id>
		<title>User Documentation</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/User_Documentation"/>
				<updated>2012-04-17T22:20:37Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Optional Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Quicklinks}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This is user documentation for OpenSimulator, mainly aimed towards administrators of the system rather than the ultimate end-users who access the environment through a viewer. If you can't find what you want here you might want to try looking in the [[Developer Documentation]].&lt;br /&gt;
&lt;br /&gt;
For a summary of what features have been implemented in OpenSimulator, please see the [[Feature Matrix]].&lt;br /&gt;
&lt;br /&gt;
== Initial Setup ==&lt;br /&gt;
* [[Download]] - Download instructions&lt;br /&gt;
* [[Dependencies]] - The other packages you need to install that OpenSimulator relies upon&lt;br /&gt;
* [[Build Instructions]] - How to build and compile OpenSimulator from source&lt;br /&gt;
* [[Configuration]] - How to configure OpenSimulator so you can get the server up and running&lt;br /&gt;
* [[Configuring Regions]] - More details on configuring regions in Regions.ini&lt;br /&gt;
* [[Configuring Simulator Parameters]] - More details on the structure and configuration simulator parameters after the initial setup.&lt;br /&gt;
* [[Database Settings]] - Detailed configurations to connect to your database&lt;br /&gt;
* [[Upgrading]] - How to upgrade your OpenSimulator version so that you can use your existing data&lt;br /&gt;
* [[Network Settings]] - NAT, Ports, Services and more.&lt;br /&gt;
* [[Firewall Settings]] - Incomplete operating system specific instructions on how to open firewall ports for external OpenSimulator access.&lt;br /&gt;
* [[Troubleshooting]] - How to trouble shoot your OpenSimulator installation.&lt;br /&gt;
* [[Tips]] - Useful tips from users like you&lt;br /&gt;
* [[OpenSim Graphics]] - Graphics that can be used on OpenSimulator websites, viewer login pages or products.&lt;br /&gt;
* [[FAQ]] - Frequently Asked Questions&lt;br /&gt;
&lt;br /&gt;
== User Guide ==&lt;br /&gt;
* [[Connecting]] - How to connect a compatible viewer to OpenSimulator&lt;br /&gt;
&lt;br /&gt;
== Administrator Guide ==&lt;br /&gt;
* [[Server Commands]] - Commands to control OpenSimulator&lt;br /&gt;
* [[OpenSim.exe Command Line Options]] - Switches when you launch OpenSimulator.&lt;br /&gt;
* [[Useful Queries]] - Some useful queries for manipulating the OpenSimulator database.&lt;br /&gt;
* [[Logging]] - Logging in OpenSimulator&lt;br /&gt;
* [[Monitoring]] - Monitoring OpenSimulator&lt;br /&gt;
* [[Automating Tasks]] - How to make administrating a walk in the park&lt;br /&gt;
* [[RemoteAdmin]] - Using the XMLRPC administration interface for executing commands remotely&lt;br /&gt;
* [[RestConsole]] - Using the remote console.&lt;br /&gt;
* [[Performance]] - How to tweak OpenSim's performance&lt;br /&gt;
* [[Console-less OpenSim]] - How to run OpenSimulator without console&lt;br /&gt;
* [[Backups]] - How to backup your OpenSimulator data.&lt;br /&gt;
&lt;br /&gt;
== Core Features ==&lt;br /&gt;
* [[Feature Matrix]] - Matrix of features currently implemented by OpenSimulator.&lt;br /&gt;
* [[Scripting Documentation]] - Everything you need to know about OpenSimulator scripting, and the list of sample scripts&lt;br /&gt;
* [[OpenSim Archives]] - Loading and saving whole region archives with OpenSimulator&lt;br /&gt;
* [[Inventory Archives|OpenSimulator Inventory Archives]] - Loading and saving user inventory items and folders with OpenSimulator&lt;br /&gt;
* [[NPC]] - Use of Non Player Characters (NPCs) in OpenSim, also known as bots.&lt;br /&gt;
* [[Custom Libraries]] - Describes how to add custom content to your OpenSimulator server&lt;br /&gt;
* [[IRCBridgeModule]] - A core OpenSimulator module for integrating IRC with a simulator.&lt;br /&gt;
* [[Hypergrid]] - Information about how to configure the experimental hypergrid architecture&lt;br /&gt;
* [[GridInfo]] - how to provide information about your grid to smart clients&lt;br /&gt;
* [[PhysicsEngines]] — Options for physics engines in OpenSimulator.&lt;br /&gt;
* [[:Category:Tech Reference|Technical Reference]] - Technical Reference Guide&lt;br /&gt;
&lt;br /&gt;
== Optional Features ==&lt;br /&gt;
* [[Feature Proposals/AutoBackup|AutoBackup]] - Module for automatically backing up a region to an OAR regularly using a different filename.&lt;br /&gt;
* [[Freeswitch Module]] - Using FreeSWITCH for voice in OpenSimulator.&lt;br /&gt;
* [[Mumble]] - Using Mumble/Whisper for voice in OpenSimulator.&lt;br /&gt;
* [[Enabling Groups]] — How to enable creating groups in your regions&lt;br /&gt;
* [[JsonStore Module]] -- Module for storing and sharing structured data among region modules and scripts&lt;br /&gt;
&lt;br /&gt;
== Experimental Features ==&lt;br /&gt;
&lt;br /&gt;
These are even more alpha than the rest of the code and may not currently work properly.&lt;br /&gt;
&lt;br /&gt;
* [[Setting Up Mega-Regions]]&lt;br /&gt;
&lt;br /&gt;
== RealXtend ==&lt;br /&gt;
* [[ModRex]] - How to setup the RealXtend server module&lt;br /&gt;
* [[RealXtend Viewer Linux]] - This tutorial describes how to use the RealXtend viewer on Linux, using wine&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
If you've written a tutorial or guide on this wiki or on an external site, then please feel free to add a link here and/or on more specific topic pages.&lt;br /&gt;
&lt;br /&gt;
=== Platform specific ===&lt;br /&gt;
* [[Linux Gridserver, the ubuntu way]] the quick and dirty way to install opensim under ubuntu (Linux)&lt;br /&gt;
* [[Wiimote]] - How to use a wiimote/nunchuk controller with the OpenSimulator viewer (Linux)&lt;br /&gt;
* [[Cacti]] - Generate Serverstats using the Cacti-Tool and SNMP (Linux)&lt;br /&gt;
* [http://sunredbeach.com/dokuwiki/doku.php?id=opensim:minimal-server Installing an openSUSE 11.1 Minimal server setup for an OpenSimulator server] - Quick and Dirty setup on an openSUSE 11.1 server&lt;br /&gt;
* [[Streaming Media in OpenSim]]&lt;br /&gt;
&lt;br /&gt;
* [http://chapter-and-metaverse.blogspot.com Chapter &amp;amp; Metaverse] - Full suite of tutorials, tips and tricks, for the Windows user (Windows) Also very useful for Linux users!&lt;br /&gt;
&lt;br /&gt;
=== Cross-platform ===&lt;br /&gt;
* [[Getting Started with Region Modules]] - The Hello World of OpenSimulator application development&lt;br /&gt;
* [[Using L3DT]] - How to create custom terrains&lt;br /&gt;
* [[Detailed cross-region terrain making]] - A workflow for creating large cross-region custom terrains&lt;br /&gt;
* [http://update.multiverse.net/wiki/index.php/About_Terrain How to make a good Terrain (includes 4 programs to use)]&lt;br /&gt;
* [http://www.nsl.tuis.ac.jp/xoops/modules/d3downloads/index.php?page=singlefile&amp;amp;cid=8&amp;amp;lid=22 Japanese Manual for Construction of OpenSimulator Server System on Linux] by NSL (Sorry, Japanese only)&lt;br /&gt;
&lt;br /&gt;
=== Application ===&lt;br /&gt;
* [http://www.scribd.com/doc/57959626/OpenSimulator-School-Quick-Start-Guide David W. Deeds' OpenSimulator School Quick Start Guide] - David W. Deeds' OpenSimulator School Quick Start Guide courtesy of Changchun American International School. Has lots of useful and interesting info, including lesson plans.&lt;br /&gt;
&lt;br /&gt;
== Gforge Projects ==&lt;br /&gt;
* [[OpenSimSearch]] - Search for your OpenSimulator&lt;br /&gt;
* [[ServerStats]] - RRD/Proc serverstats using the OpenSimulator module for Berlios Serverstats (Linux)&lt;br /&gt;
&amp;lt;cleanpage title=hide cats=hide /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Users]]&lt;br /&gt;
[[Category:Support]]&lt;br /&gt;
[[Category:Help]]&lt;br /&gt;
[[Category:Configuration]]&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore</id>
		<title>OSSL Script Library/JsonStore</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore"/>
				<updated>2012-04-17T22:16:05Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This page describes two scripts, a generator and a consumer, that demonstrate how to use the JsonStore JsonStoreRead and JsonStoreTake operations for creating a master/worker pair of scripts. Place the generator script in an object and the consumer script in another object. Touch the generator to start the process. &lt;br /&gt;
&lt;br /&gt;
To see the value of the master/worker pattern, try to make multiple copies of the consumer object. Each one will read tasks created by the generator.&lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling the JsonStore Module ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable the JsonStore module in OpenSim.ini. Add the following to enable the module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Generator Script ==&lt;br /&gt;
&lt;br /&gt;
The generator script writes values to a shared array where consumers can pull those values. The script uses the global store (public scratch storage space) to share the identity of the Json store that it creates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
integer iCounter = 0;&lt;br /&gt;
key kStoreID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;running...&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Create a JsonStore initialized with an empty array associated with the key 'Event'&lt;br /&gt;
        kStoreID = JsonCreateStore(&amp;quot;{'Event' : []}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Save the store that was just created in the global store, this makes it easier for&lt;br /&gt;
        // other scripts to find; an alternative is to say the store id in a private channel&lt;br /&gt;
        JsonSetValue(kGlobalStore,sStoreName,(string)kStoreID);&lt;br /&gt;
&lt;br /&gt;
        // Start a timer that will generate counters periodically&lt;br /&gt;
        llSetTimerEvent(1.0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a new counter and add it to the end of the Event array&lt;br /&gt;
        iCounter += 1;&lt;br /&gt;
        JsonSetValue(kStoreID,&amp;quot;Event[+]&amp;quot;,(string)iCounter);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        // When the test is done, remove the identity of the store and destroy it&lt;br /&gt;
        JsonRemoveValue(kGlobalStore,sStoreName);&lt;br /&gt;
        JsonDestroyStore(kStoreID);&lt;br /&gt;
&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Consumer Script ==&lt;br /&gt;
&lt;br /&gt;
The consumer script waits for the generator to create the store and place its identity into the global store. At that&lt;br /&gt;
point it begins to read values from the generator's store. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
key kStoreID;&lt;br /&gt;
key kReqID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request for the identity of the generator's store&lt;br /&gt;
        // This posts a request, when the value is available a link message event will be fired&lt;br /&gt;
        kReqID = JsonReadValue(kGlobalStore,sStoreName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;shared store id: &amp;quot; + msg);&lt;br /&gt;
        kStoreID = (key)msg;&lt;br /&gt;
&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request that will take a value (remove it from the store) when it is available&lt;br /&gt;
        // A link_message will be fired when the value is available&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;read &amp;quot; + msg);&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore</id>
		<title>OSSL Script Library/JsonStore</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore"/>
				<updated>2012-04-17T22:13:08Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* Enabling modInvoke() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling the JsonStore Module ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable the JsonStore module in OpenSim.ini. Add the following to enable the module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Generator Script ==&lt;br /&gt;
&lt;br /&gt;
The generator script writes values to a shared array where consumers can pull those values. The script uses the global store (public scratch storage space) to share the identity of the Json store that it creates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
integer iCounter = 0;&lt;br /&gt;
key kStoreID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;running...&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Create a JsonStore initialized with an empty array associated with the key 'Event'&lt;br /&gt;
        kStoreID = JsonCreateStore(&amp;quot;{'Event' : []}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Save the store that was just created in the global store, this makes it easier for&lt;br /&gt;
        // other scripts to find; an alternative is to say the store id in a private channel&lt;br /&gt;
        JsonSetValue(kGlobalStore,sStoreName,(string)kStoreID);&lt;br /&gt;
&lt;br /&gt;
        // Start a timer that will generate counters periodically&lt;br /&gt;
        llSetTimerEvent(1.0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a new counter and add it to the end of the Event array&lt;br /&gt;
        iCounter += 1;&lt;br /&gt;
        JsonSetValue(kStoreID,&amp;quot;Event[+]&amp;quot;,(string)iCounter);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        // When the test is done, remove the identity of the store and destroy it&lt;br /&gt;
        JsonRemoveValue(kGlobalStore,sStoreName);&lt;br /&gt;
        JsonDestroyStore(kStoreID);&lt;br /&gt;
&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Consumer Script ==&lt;br /&gt;
&lt;br /&gt;
The consumer script waits for the generator to create the store and place its identity into the global store. At that&lt;br /&gt;
point it begins to read values from the generator's store. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
key kStoreID;&lt;br /&gt;
key kReqID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request for the identity of the generator's store&lt;br /&gt;
        // This posts a request, when the value is available a link message event will be fired&lt;br /&gt;
        kReqID = JsonReadValue(kGlobalStore,sStoreName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;shared store id: &amp;quot; + msg);&lt;br /&gt;
        kStoreID = (key)msg;&lt;br /&gt;
&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request that will take a value (remove it from the store) when it is available&lt;br /&gt;
        // A link_message will be fired when the value is available&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;read &amp;quot; + msg);&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore</id>
		<title>OSSL Script Library/JsonStore</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore"/>
				<updated>2012-04-17T22:12:43Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Generator Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable the JsonStore module in OpenSim.ini. Add the following to enable the module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Generator Script ==&lt;br /&gt;
&lt;br /&gt;
The generator script writes values to a shared array where consumers can pull those values. The script uses the global store (public scratch storage space) to share the identity of the Json store that it creates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
integer iCounter = 0;&lt;br /&gt;
key kStoreID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;running...&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Create a JsonStore initialized with an empty array associated with the key 'Event'&lt;br /&gt;
        kStoreID = JsonCreateStore(&amp;quot;{'Event' : []}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Save the store that was just created in the global store, this makes it easier for&lt;br /&gt;
        // other scripts to find; an alternative is to say the store id in a private channel&lt;br /&gt;
        JsonSetValue(kGlobalStore,sStoreName,(string)kStoreID);&lt;br /&gt;
&lt;br /&gt;
        // Start a timer that will generate counters periodically&lt;br /&gt;
        llSetTimerEvent(1.0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a new counter and add it to the end of the Event array&lt;br /&gt;
        iCounter += 1;&lt;br /&gt;
        JsonSetValue(kStoreID,&amp;quot;Event[+]&amp;quot;,(string)iCounter);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        // When the test is done, remove the identity of the store and destroy it&lt;br /&gt;
        JsonRemoveValue(kGlobalStore,sStoreName);&lt;br /&gt;
        JsonDestroyStore(kStoreID);&lt;br /&gt;
&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Consumer Script ==&lt;br /&gt;
&lt;br /&gt;
The consumer script waits for the generator to create the store and place its identity into the global store. At that&lt;br /&gt;
point it begins to read values from the generator's store. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
key kStoreID;&lt;br /&gt;
key kReqID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request for the identity of the generator's store&lt;br /&gt;
        // This posts a request, when the value is available a link message event will be fired&lt;br /&gt;
        kReqID = JsonReadValue(kGlobalStore,sStoreName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;shared store id: &amp;quot; + msg);&lt;br /&gt;
        kStoreID = (key)msg;&lt;br /&gt;
&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request that will take a value (remove it from the store) when it is available&lt;br /&gt;
        // A link_message will be fired when the value is available&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;read &amp;quot; + msg);&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore</id>
		<title>OSSL Script Library/JsonStore</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/JsonStore"/>
				<updated>2012-04-17T22:09:41Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Created page with &amp;quot;== Introduction ==  This functionality current only exists in OpenSimulator development code (0.7.4-dev).  == Enabling modInvoke() ==  The first thing is to enable the JsonStore ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This functionality current only exists in OpenSimulator development code (0.7.4-dev).&lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable the JsonStore module in OpenSim.ini. Add the following to enable the module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[JsonStore]&lt;br /&gt;
Enabled = True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Generator Script ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
integer iCounter = 0;&lt;br /&gt;
key kStoreID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;running...&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Create a JsonStore initialized with an empty array associated with the key 'Event'&lt;br /&gt;
        kStoreID = JsonCreateStore(&amp;quot;{'Event' : []}&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // Save the store that was just created in the global store, this makes it easier for&lt;br /&gt;
        // other scripts to find; an alternative is to say the store id in a private channel&lt;br /&gt;
        JsonSetValue(kGlobalStore,sStoreName,(string)kStoreID);&lt;br /&gt;
&lt;br /&gt;
        // Start a timer that will generate counters periodically&lt;br /&gt;
        llSetTimerEvent(1.0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        // Generate a new counter and add it to the end of the Event array&lt;br /&gt;
        iCounter += 1;&lt;br /&gt;
        JsonSetValue(kStoreID,&amp;quot;Event[+]&amp;quot;,(string)iCounter);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        // When the test is done, remove the identity of the store and destroy it&lt;br /&gt;
        JsonRemoveValue(kGlobalStore,sStoreName);&lt;br /&gt;
        JsonDestroyStore(kStoreID);&lt;br /&gt;
&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Consumer Script ==&lt;br /&gt;
&lt;br /&gt;
The consumer script waits for the generator to create the store and place its identity into the global store. At that&lt;br /&gt;
point it begins to read values from the generator's store. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
string sStoreName = &amp;quot;JsonStoreTest&amp;quot;;&lt;br /&gt;
key kGlobalStore = (key)NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
key kStoreID;&lt;br /&gt;
key kReqID;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request for the identity of the generator's store&lt;br /&gt;
        // This posts a request, when the value is available a link message event will be fired&lt;br /&gt;
        kReqID = JsonReadValue(kGlobalStore,sStoreName);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;shared store id: &amp;quot; + msg);&lt;br /&gt;
        kStoreID = (key)msg;&lt;br /&gt;
&lt;br /&gt;
        state running;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // Set up a request that will take a value (remove it from the store) when it is available&lt;br /&gt;
        // A link_message will be fired when the value is available&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer result, string msg, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (sender != -1)&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        llOwnerSay(&amp;quot;read &amp;quot; + msg);&lt;br /&gt;
        kReqID = JsonTakeValue(kStoreID,&amp;quot;Event[0]&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer i)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library</id>
		<title>OSSL Script Library</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library"/>
				<updated>2012-04-17T21:53:38Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Library */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Quicklinks}} {{information}} &lt;br /&gt;
&lt;br /&gt;
= OSSL Script Library =&lt;br /&gt;
&lt;br /&gt;
=== Rules for posting: ===&lt;br /&gt;
&lt;br /&gt;
# Your script '''MUST''' depend on at least one [[OSSL Functions|OSSL function]], or on other OpenSim-specific functions. &lt;br /&gt;
# Test your script in-world, and make sure it works, so that other people can use it. &lt;br /&gt;
# No copies of scripts which already exist on this wiki, unless it exists in your own user page. &lt;br /&gt;
# Please, no short scripts (5 lines or less), and definitely no one-liners! &lt;br /&gt;
# Make sure to read &amp;quot;[[OSSL Script Library#Adding your script to the Library|Adding your script to the Library]]&amp;quot; for important info!&lt;br /&gt;
&lt;br /&gt;
== The Library ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;sortable&amp;quot; border=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;3&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Script Name &lt;br /&gt;
| Posted by: &lt;br /&gt;
| Description&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/ModSendCommand|ModSendCommand]] &lt;br /&gt;
| [[User:Justincc|Justincc]] &lt;br /&gt;
| Demonstrates the use of an in-world script to communicate with a specific OpenSimulator module.&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/ModInvoke|ModInvoke]] &lt;br /&gt;
| [[User:Cmickeyb|Cmickeyb]] &lt;br /&gt;
| Demonstrates the use of an in-world script to invoke functions defined in an OpenSimulator module.&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/JsonStore|JsonStore]] &lt;br /&gt;
| [[User:Cmickeyb|Cmickeyb]] &lt;br /&gt;
| Demonstrates the use of the JsonStore module for managing structured data in an LSL script.&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/OpenSim Radio|OpenSimulator Radio]] &lt;br /&gt;
| [[User:Fritigern|Fritigern]] &lt;br /&gt;
| A dialog controlled radio for OpenSimulator. Uses OSSL functions to read stations from a notecard,&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/Persist NPC|Persist NPC]] &lt;br /&gt;
| [[User:Marcus Llewellyn|Marcus Llewellyn]] &lt;br /&gt;
| A short example of a method for persisting an NPC across simulator restarts.&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/Simple Notecard Reader|Simple Notecard Reader]] &lt;br /&gt;
| [[User:Fritigern|Fritigern]] &lt;br /&gt;
| Reading notecards in OSSL is easy. This script is more of an example than a fully useful script, but it does work. Use it in your own scripts!&lt;br /&gt;
|-&lt;br /&gt;
| [[OSSL Script Library/OSSL Poseball|OSSL Poseball]] &lt;br /&gt;
| [[User:Fritigern|Fritigern]] &lt;br /&gt;
| Poseball script, written from scratch, using [[osAvatarPlayAnimation]]() and [[osAvatarStopAnimation]]()&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Adding your script to the Library ==&lt;br /&gt;
&lt;br /&gt;
* First select, right-click, and copy the following code:&lt;br /&gt;
&amp;lt;pre&amp;gt; |-&lt;br /&gt;
 | [[OSSL Script Library/SCRIPT_NAME|SCRIPT_NAME]]&lt;br /&gt;
 | [[User:YOURNAME|YOURNAME]]&lt;br /&gt;
 | DESCRIPTION&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
* Edit the Library section, and paste the above code to the end of the list,, but just above &amp;quot;'''|}'''&amp;quot; &lt;br /&gt;
* Replace &amp;quot;'''SCRIPT_NAME'''&amp;quot; with the name of your script. Make sure to change both instances. &lt;br /&gt;
* Replace &amp;quot;'''YOURNAME'''&amp;quot; with your wiki username. Make sure to change both instances. &lt;br /&gt;
* Replace the word '''DESCRIPTION''' with a short desription of what your script does. &lt;br /&gt;
* Click the &amp;quot;'''Show preview'''&amp;quot; button to check and see if everything works as it's supposed to. &lt;br /&gt;
* If something looks wrong, change whatever is not right, and click &amp;quot;'''Show preview'''&amp;quot; again. &lt;br /&gt;
* If everything looks okay, click the &amp;quot;'''Save page'''&amp;quot; button. &lt;br /&gt;
* In the table, look up the name of your script (it should be red) and click it. This will create a new page. &lt;br /&gt;
* In the new page, Type '''&amp;lt;nowiki&amp;gt;&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&amp;lt;/nowiki&amp;gt;'''. This will make the wiki recognise your script as LSL, and apply the correct source highlighting. &lt;br /&gt;
* Paste your script into the page. &lt;br /&gt;
* Immediately below your script, type '''&amp;lt;nowiki&amp;gt;&amp;lt;/source&amp;gt;&amp;lt;/nowiki&amp;gt;'''. This will tell the wiki where your script ends. &lt;br /&gt;
* Optionally add an introductory text, though you are encouraged to place usage instructions for your script in your script's comments. &lt;br /&gt;
* Preview the page by clicking the &amp;quot;'''Show preview'''&amp;quot; button. &lt;br /&gt;
* Make changes where nescessary and click the &amp;quot;'''Show preview'''&amp;quot; button again. &lt;br /&gt;
* Save your page by pressing the &amp;quot;'''Save page'''&amp;quot; button, and presto!&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;br /&gt;
[[Category:OSSL]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-26T16:25:16Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Sockets;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenMetaverse;&lt;br /&gt;
using OpenMetaverse.StructuredData;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private static readonly ILog m_log =&lt;br /&gt;
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;
&lt;br /&gt;
        private IConfig m_config = null;&lt;br /&gt;
        private bool m_enabled = true;&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        &lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] start configuration&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            try &lt;br /&gt;
            {&lt;br /&gt;
                if ((m_config = config.Configs[&amp;quot;ModInvoke&amp;quot;]) != null)&lt;br /&gt;
                    m_enabled = m_config.GetBoolean(&amp;quot;Enabled&amp;quot;, m_enabled);&lt;br /&gt;
            }&lt;br /&gt;
            catch (Exception e)&lt;br /&gt;
            {&lt;br /&gt;
                m_log.ErrorFormat(&amp;quot;[ModInvoke] initialization error: {0}&amp;quot;,e.Message);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            m_log.ErrorFormat(&amp;quot;[ModInvoke] module {0} enabled&amp;quot;,(m_enabled ? &amp;quot;is&amp;quot; : &amp;quot;is not&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void PostInitialise()&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Close() { }&lt;br /&gt;
        public void AddRegion(Scene scene) { }&lt;br /&gt;
        public void RemoveRegion(Scene scene)  { }&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled)&lt;br /&gt;
            {&lt;br /&gt;
                m_scene = scene;&lt;br /&gt;
                m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
                if (m_comms == null)&lt;br /&gt;
                {&lt;br /&gt;
                    m_log.WarnFormat(&amp;quot;[ModInvoke] ScriptModuleComms interface not defined&amp;quot;);&lt;br /&gt;
                    m_enabled = false;&lt;br /&gt;
&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest0&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest1&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest2&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest3&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest4&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest5&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest6&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest7&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest8&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        public string ModTest0(UUID hostID, UUID scriptID)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest0 parameter&amp;quot;);&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public string ModTest1(UUID hostID, UUID scriptID, string value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest1 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int ModTest2(UUID hostID, UUID scriptID, int value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest2 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public float ModTest3(UUID hostID, UUID scriptID, float value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest3 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public UUID ModTest4(UUID hostID, UUID scriptID, UUID value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest4 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Vector3 ModTest5(UUID hostID, UUID scriptID, OpenMetaverse.Vector3 value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest5 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Quaternion ModTest6(UUID hostID, UUID scriptID, OpenMetaverse.Quaternion value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest6 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest7(UUID hostID, UUID scriptID, int count, string val)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[count];&lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
                result[i] = val;&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest8(UUID hostID, UUID scriptID, object[] lparm)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[lparm.Length];&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)&lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-26T16:24:53Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Copyright (c) Contributors &lt;br /&gt;
 * See CONTRIBUTORS.TXT for a full list of copyright holders.&lt;br /&gt;
 *&lt;br /&gt;
 * Redistribution and use in source and binary forms, with or without&lt;br /&gt;
 * modification, are permitted provided that the following conditions are met:&lt;br /&gt;
 *     * Redistributions of source code must retain the above copyright&lt;br /&gt;
 *       notice, this list of conditions and the following disclaimer.&lt;br /&gt;
 *     * Redistributions in binary form must reproduce the above copyright&lt;br /&gt;
 *       notice, this list of conditions and the following disclaimer in the&lt;br /&gt;
 *       documentation and/or other materials provided with the distribution.&lt;br /&gt;
 *     * Neither the name of the OpenSim Project nor the&lt;br /&gt;
 *       names of its contributors may be used to endorse or promote products&lt;br /&gt;
 *       derived from this software without specific prior written permission.&lt;br /&gt;
 *&lt;br /&gt;
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY&lt;br /&gt;
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED&lt;br /&gt;
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&lt;br /&gt;
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY&lt;br /&gt;
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES&lt;br /&gt;
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;&lt;br /&gt;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND&lt;br /&gt;
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT&lt;br /&gt;
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS&lt;br /&gt;
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
 */&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Sockets;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenMetaverse;&lt;br /&gt;
using OpenMetaverse.StructuredData;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private static readonly ILog m_log =&lt;br /&gt;
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);&lt;br /&gt;
&lt;br /&gt;
        private IConfig m_config = null;&lt;br /&gt;
        private bool m_enabled = true;&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        &lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] start configuration&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
            try &lt;br /&gt;
            {&lt;br /&gt;
                if ((m_config = config.Configs[&amp;quot;ModInvoke&amp;quot;]) != null)&lt;br /&gt;
                    m_enabled = m_config.GetBoolean(&amp;quot;Enabled&amp;quot;, m_enabled);&lt;br /&gt;
            }&lt;br /&gt;
            catch (Exception e)&lt;br /&gt;
            {&lt;br /&gt;
                m_log.ErrorFormat(&amp;quot;[ModInvoke] initialization error: {0}&amp;quot;,e.Message);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            m_log.ErrorFormat(&amp;quot;[ModInvoke] module {0} enabled&amp;quot;,(m_enabled ? &amp;quot;is&amp;quot; : &amp;quot;is not&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void PostInitialise()&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Close() { }&lt;br /&gt;
        public void AddRegion(Scene scene) { }&lt;br /&gt;
        public void RemoveRegion(Scene scene)  { }&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            if (m_enabled)&lt;br /&gt;
            {&lt;br /&gt;
                m_scene = scene;&lt;br /&gt;
                m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
                if (m_comms == null)&lt;br /&gt;
                {&lt;br /&gt;
                    m_log.WarnFormat(&amp;quot;[ModInvoke] ScriptModuleComms interface not defined&amp;quot;);&lt;br /&gt;
                    m_enabled = false;&lt;br /&gt;
&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest0&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest1&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest2&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest3&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest4&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest5&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest6&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest7&amp;quot;);&lt;br /&gt;
                m_comms.RegisterScriptInvocation(this,&amp;quot;ModTest8&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        public string ModTest0(UUID hostID, UUID scriptID)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest0 parameter&amp;quot;);&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public string ModTest1(UUID hostID, UUID scriptID, string value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest1 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int ModTest2(UUID hostID, UUID scriptID, int value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest2 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public float ModTest3(UUID hostID, UUID scriptID, float value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest3 parameter: {0}&amp;quot;,value);&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public UUID ModTest4(UUID hostID, UUID scriptID, UUID value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest4 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Vector3 ModTest5(UUID hostID, UUID scriptID, OpenMetaverse.Vector3 value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest5 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public OpenMetaverse.Quaternion ModTest6(UUID hostID, UUID scriptID, OpenMetaverse.Quaternion value)&lt;br /&gt;
        {&lt;br /&gt;
            m_log.WarnFormat(&amp;quot;[ModInvoke] ModTest6 parameter: {0}&amp;quot;,value.ToString());&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest7(UUID hostID, UUID scriptID, int count, string val)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[count];&lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
                result[i] = val;&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public object[] ModTest8(UUID hostID, UUID scriptID, object[] lparm)&lt;br /&gt;
        {&lt;br /&gt;
            object[] result = new object[lparm.Length];&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)&lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];&lt;br /&gt;
            &lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-25T05:34:38Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using OpenMetaverse;                                                                                                                                    &lt;br /&gt;
using OpenMetaverse.StructuredData;                                                                                                                     &lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest4&amp;quot;,SI_ModTest4,new Type[] { typeof(UUID) }, typeof(UUID));                                     &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest5&amp;quot;,SI_ModTest5,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(OpenMetaverse.Vector3) },typeof(OpenMetaverse.Vector3));                           &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest6&amp;quot;,SI_ModTest6,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(OpenMetaverse.Quaternion)},&lt;br /&gt;
                                             typeof(OpenMetaverse.Quaternion));                     &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest7&amp;quot;,SI_ModTest7,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(int), typeof(string) },typeof(object[]));                                          &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest8&amp;quot;,SI_ModTest8,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(object[]) },typeof(object[]));                                                    &lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest4(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            UUID value = (UUID)parray[0];                                                                                                                 &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest5(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            OpenMetaverse.Vector3 value = (OpenMetaverse.Vector3)parray[0];                                                                               &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest6(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            OpenMetaverse.Quaternion value = (OpenMetaverse.Quaternion)parray[0];                                                                         &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest7(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            int count = (int)parray[0];                                                                                                                   &lt;br /&gt;
            string val = (string)parray[1];                                                                                                               &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            object[] result = new object[count];                                                                                                          &lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)                                                                                                               &lt;br /&gt;
                result[i] = val;                                                                                                                          &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            return result;                                                                                                                                &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest8(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            object[] lparm = (object[])parray[0];                                                                                                         &lt;br /&gt;
            object[] result = new object[lparm.Length];                                                                                                   &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)                                                                                                        &lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];                                                                                                  &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            return result;                                                                                                                                &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-25T05:33:55Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest4&amp;quot;,SI_ModTest4,new Type[] { typeof(UUID) }, typeof(UUID));                                     &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest5&amp;quot;,SI_ModTest5,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(OpenMetaverse.Vector3) },typeof(OpenMetaverse.Vector3));                           &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest6&amp;quot;,SI_ModTest6,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(OpenMetaverse.Quaternion)},&lt;br /&gt;
                                             typeof(OpenMetaverse.Quaternion));                     &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest7&amp;quot;,SI_ModTest7,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(int), typeof(string) },typeof(object[]));                                          &lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest8&amp;quot;,SI_ModTest8,                                                                                &lt;br /&gt;
                                             new Type[] { typeof(object[]) },typeof(object[]));                                                    &lt;br /&gt;
       }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest4(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            UUID value = (UUID)parray[0];                                                                                                                 &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest5(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            OpenMetaverse.Vector3 value = (OpenMetaverse.Vector3)parray[0];                                                                               &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest6(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            OpenMetaverse.Quaternion value = (OpenMetaverse.Quaternion)parray[0];                                                                         &lt;br /&gt;
            return value;                                                                                                                                 &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest7(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            int count = (int)parray[0];                                                                                                                   &lt;br /&gt;
            string val = (string)parray[1];                                                                                                               &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            object[] result = new object[count];                                                                                                          &lt;br /&gt;
            for (int i = 0; i &amp;lt; count; i++)                                                                                                               &lt;br /&gt;
                result[i] = val;                                                                                                                          &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            return result;                                                                                                                                &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
        protected object SI_ModTest8(UUID scriptID, object[] parray)                                                                                      &lt;br /&gt;
        {                                                                                                                                                 &lt;br /&gt;
            object[] lparm = (object[])parray[0];                                                                                                         &lt;br /&gt;
            object[] result = new object[lparm.Length];                                                                                                   &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            for (int i = 0; i &amp;lt; lparm.Length; i++)                                                                                                        &lt;br /&gt;
                result[lparm.Length - i - 1] = lparm[i];                                                                                                  &lt;br /&gt;
                                                                                                                                                          &lt;br /&gt;
            return result;                                                                                                                                &lt;br /&gt;
        }                                                                                                                                                 &lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-25T05:30:32Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The In-world Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = &amp;quot;csharp&amp;quot;&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lsl&amp;quot;&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
        &lt;br /&gt;
        key v4 = ModTest4(llGetKey());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest4: &amp;quot; + (string)v4);&lt;br /&gt;
        &lt;br /&gt;
        vector v5 = ModTest5(llGetPos());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest5: &amp;quot; + (string)v5);&lt;br /&gt;
        &lt;br /&gt;
        rotation v6 = ModTest6(llGetRot());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest6: &amp;quot; + (string)v6);&lt;br /&gt;
        &lt;br /&gt;
        list v7 = ModTest7(5,&amp;quot;hello&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + (string)llGetListLength(v7));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest7: &amp;quot; + llList2CSV(v7));&lt;br /&gt;
        &lt;br /&gt;
        list v8 = [&amp;quot;a&amp;quot;, 1, llGetKey(), llGetPos(), llGetRot()];&lt;br /&gt;
        list v9 = ModTest8(v8);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + (string)llGetListLength(v9));&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest8: &amp;quot; + llList2CSV(v9));&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-15T20:54:41Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
Here's the region module that implements several functions to be provided to scripts in the region. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-15T20:53:50Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: /* The Region Module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke</id>
		<title>OSSL Script Library/ModInvoke</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke"/>
				<updated>2012-03-15T20:53:00Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Created page with &amp;quot;You can invoke functions defined in a region module from a script using the modInvoke() family of functions.   == Enabling modInvoke() ==  The first thing is to enable modSendCom...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You can invoke functions defined in a region module from a script using the modInvoke() family of functions. &lt;br /&gt;
&lt;br /&gt;
== Enabling modInvoke() ==&lt;br /&gt;
&lt;br /&gt;
The first thing is to enable modSendCommand() in OpenSim.ini. Make sure the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AllowMODFunctions = true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is set to true and uncommented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The Region Module ==&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Copyright (c) Contributors &lt;br /&gt;
 * See CONTRIBUTORS.TXT for a full list of copyright holders.&lt;br /&gt;
 *&lt;br /&gt;
 * Redistribution and use in source and binary forms, with or without&lt;br /&gt;
 * modification, are permitted provided that the following conditions are met:&lt;br /&gt;
 *     * Redistributions of source code must retain the above copyright&lt;br /&gt;
 *       notice, this list of conditions and the following disclaimer.&lt;br /&gt;
 *     * Redistributions in binary form must reproduce the above copyright&lt;br /&gt;
 *       notice, this list of conditions and the following disclaimer in the&lt;br /&gt;
 *       documentation and/or other materials provided with the distribution.&lt;br /&gt;
 *     * Neither the name of the OpenSim Project nor the&lt;br /&gt;
 *       names of its contributors may be used to endorse or promote products&lt;br /&gt;
 *       derived from this software without specific prior written permission.&lt;br /&gt;
 *&lt;br /&gt;
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY&lt;br /&gt;
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED&lt;br /&gt;
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&lt;br /&gt;
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY&lt;br /&gt;
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES&lt;br /&gt;
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;&lt;br /&gt;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND&lt;br /&gt;
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT&lt;br /&gt;
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS&lt;br /&gt;
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
 */&lt;br /&gt;
using Mono.Addins;&lt;br /&gt;
&lt;br /&gt;
using System;&lt;br /&gt;
using System.Reflection;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Sockets;&lt;br /&gt;
using log4net;&lt;br /&gt;
using Nini.Config;&lt;br /&gt;
using OpenMetaverse;&lt;br /&gt;
using OpenMetaverse.StructuredData;&lt;br /&gt;
using OpenSim.Framework;&lt;br /&gt;
using OpenSim.Region.Framework.Interfaces;&lt;br /&gt;
using OpenSim.Region.Framework.Scenes;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Text.RegularExpressions;&lt;br /&gt;
&lt;br /&gt;
            &lt;br /&gt;
[assembly: Addin(&amp;quot;ModInvokeTest&amp;quot;, &amp;quot;0.1&amp;quot;)]&lt;br /&gt;
[assembly: AddinDependency(&amp;quot;OpenSim&amp;quot;, &amp;quot;0.5&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
namespace ModInvokeTest&lt;br /&gt;
{&lt;br /&gt;
    [Extension(Path = &amp;quot;/OpenSim/RegionModules&amp;quot;, NodeName = &amp;quot;RegionModule&amp;quot;)]&lt;br /&gt;
&lt;br /&gt;
    public class ModInvokeTestModule  : INonSharedRegionModule&lt;br /&gt;
    {&lt;br /&gt;
        private Scene m_scene = null;&lt;br /&gt;
        private IScriptModuleComms m_comms;&lt;br /&gt;
        &lt;br /&gt;
#region IRegionModule Members&lt;br /&gt;
&lt;br /&gt;
        public string Name&lt;br /&gt;
        {&lt;br /&gt;
            get { return this.GetType().Name; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Initialise(IConfigSource config) {}&lt;br /&gt;
        public void PostInitialise(){}&lt;br /&gt;
        public void Close(){}&lt;br /&gt;
        public void AddRegion(Scene scene){}&lt;br /&gt;
        public void RemoveRegion(Scene scene){}&lt;br /&gt;
&lt;br /&gt;
        public void RegionLoaded(Scene scene)&lt;br /&gt;
        {&lt;br /&gt;
            m_scene = scene;&lt;br /&gt;
            m_comms = m_scene.RequestModuleInterface&amp;lt;IScriptModuleComms&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest0&amp;quot;,SI_ModTest0,new Type[] { }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest1&amp;quot;,SI_ModTest1,new Type[] { typeof(string) }, typeof(string));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest2&amp;quot;,SI_ModTest2,new Type[] { typeof(int) }, typeof(int));&lt;br /&gt;
            m_comms.RegisterScriptInvocation(&amp;quot;ModTest3&amp;quot;,SI_ModTest3,new Type[] { typeof(float) }, typeof(float));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Type ReplaceableInterface&lt;br /&gt;
        {&lt;br /&gt;
            get { return null; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
#endregion&lt;br /&gt;
&lt;br /&gt;
#region ScriptInvocationInteface&lt;br /&gt;
        protected object SI_ModTest0(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            return &amp;quot;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest1(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            string value = (string)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
       protected object SI_ModTest2(UUID scriptID, object[] parray)&lt;br /&gt;
       {&lt;br /&gt;
            int value = (int)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected object SI_ModTest3(UUID scriptID, object[] parray)&lt;br /&gt;
        {&lt;br /&gt;
            float value = (float)parray[0];&lt;br /&gt;
            return value;&lt;br /&gt;
        }&lt;br /&gt;
#endregion&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The module registers functions through the IScriptModuleComms RegisterScriptInvocation() method. This method takes the name of the function, an invocation delegate, an array of types used to validate parameters to the function, and a return type. &lt;br /&gt;
&lt;br /&gt;
The functions in the region module can assume that the parameters passed through the argument array match the signature that was registered. That is, the function in the region module does not need to perform any kind of type checking.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The In-world Script ==&lt;br /&gt;
&lt;br /&gt;
Here's the in-world script that calls the functions defined in the region module. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0, &amp;quot;Script running&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest0: &amp;quot; + ModTest0());&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest1: &amp;quot; + ModTest1(&amp;quot;one&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
        integer v2 = ModTest2(2) + 2;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest2: &amp;quot; + (string)v2);&lt;br /&gt;
        &lt;br /&gt;
        float v3 = ModTest3(3.14) + 4.56;&lt;br /&gt;
        llOwnerSay(&amp;quot;ModTest3: &amp;quot; + (string)v3);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/OSSL_Implemented</id>
		<title>OSSL Implemented</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/OSSL_Implemented"/>
				<updated>2009-03-08T05:17:05Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| border=1 style=&amp;quot;border-collapse:collapse;th background-color:#666;width:100%;text-align:left;&amp;quot;&lt;br /&gt;
! style=&amp;quot;background-color:#D2ECD2;&amp;quot; | Function&lt;br /&gt;
! style=&amp;quot;background-color:#D2ECD2;&amp;quot; | Explanation&lt;br /&gt;
! style=&amp;quot;background-color:#D2ECD2;&amp;quot; | Examples&lt;br /&gt;
! style=&amp;quot;background-color:#D2ECD2;&amp;quot; | Threat Level&lt;br /&gt;
|-&lt;br /&gt;
| string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, int refreshTimer);&lt;br /&gt;
| Loads a web texture on a prim. Should work for any image URL (including php scripts) that Opensim can render. [Note refreshTimer may not yet be implemented, use a timer event and recall the function to get  the same effect]&lt;br /&gt;
| [[osSetDynamicTextureURL_example1|example 1]]&lt;br /&gt;
[[osSetDynamictextureURL_example2|example 2]]&lt;br /&gt;
| VeryLow&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osSetDynamicTextureData(&amp;quot;&amp;quot;, &amp;quot;vector&amp;quot;, drawList, &amp;quot;1024&amp;quot;, 0);&lt;br /&gt;
| Writes text and vector graphics onto a prim face. See list of implemented [[OSSL_TextureDrawing|Functions]]. NOTE:As of r8206 (above v0.6.2) width,height and alpha value can be passed e.g.  osSetDynamicTextureData(&amp;quot;&amp;quot;, &amp;quot;vector&amp;quot;, drawList, &amp;quot;width:64,height:1024:alpha:0&amp;quot;, 0);&lt;br /&gt;
To turn off the alpha layer completely use &amp;quot;alpha:false&amp;quot; in the optional parameters&lt;br /&gt;
| [[osSetDynamicdata_example1|example 1]]&lt;br /&gt;
| VeryLow&lt;br /&gt;
|-&lt;br /&gt;
| double osTerrainGetHeight(int x, int y);&lt;br /&gt;
| Gets height of terrain&lt;br /&gt;
|&lt;br /&gt;
| None&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| int osTerrainSetHeight(int x, int y);&lt;br /&gt;
| Sets height of terrain&lt;br /&gt;
|&lt;br /&gt;
| High&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| int osRegionRestart(double seconds);&lt;br /&gt;
| Restarts the region&lt;br /&gt;
|&lt;br /&gt;
| High&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| void osRegionNotice(string msg);&lt;br /&gt;
| Sends a notice to the region&lt;br /&gt;
|&lt;br /&gt;
| VeryHigh&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| System.Collections.Hashtable osParseJSON(string JSON);&lt;br /&gt;
| returns a hashtable containing the structured JSON contents (c# only)&lt;br /&gt;
| [[osParseJSON_example1|example 1]]&lt;br /&gt;
| None&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osMessageObject(key objectId, string message);&lt;br /&gt;
| sends a string to the object identified by objectId, the receiving object requires to implement the method dataserver( key queryid, string data ) in a contained script(s). The queryid passed will be the id of the calling object.&lt;br /&gt;
|&lt;br /&gt;
| Low&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osTeleportAgent(key agentId, string regionName, vector position, vector lookAt);&lt;br /&gt;
| Teleports agent ''agentId'' to region ''regionName'', region-local position ''position'', with looking direction ''lookAt'' without asking the user first (in contrast to ''llMapDestination''). This function works only in scripts '''owned by''' the region's master-avatar.&lt;br /&gt;
|&lt;br /&gt;
| High&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osTeleportAgent(key agentId, vector position, vector lookAt);&lt;br /&gt;
| Teleports agent ''agentId'' to position ''position'' in the same region, with looking direction ''lookAt'' without asking the user first (in contrast to ''llMapDestination''). This function works only in scripts '''owned by''' the region's master-avatar.&lt;br /&gt;
|&lt;br /&gt;
| High&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osConsoleCommand(string command);&lt;br /&gt;
| Issues command as if from the server console. &amp;quot;Severe&amp;quot; threat level. Eg.: osConsoleCommand(&amp;quot;link-region X Y URL port&amp;quot;).&lt;br /&gt;
|&lt;br /&gt;
| Severe&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| osMakeNotecard(string cardname, list cardlines);&lt;br /&gt;
| Writes a new notecard into the containing prim's inventory. The list parameter may contain only strings. Eg.: osMakeNotecard(&amp;quot;new card&amp;quot;, [&amp;quot;line-1&amp;quot;, &amp;quot;line-2&amp;quot;, &amp;quot;line-3&amp;quot;]).&lt;br /&gt;
|&lt;br /&gt;
| High&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| string osGetGridNick();&lt;br /&gt;
| Return the nick name of the grid as per the config .ini file.&lt;br /&gt;
|&lt;br /&gt;
| Moderate&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| string osGetGridName();&lt;br /&gt;
| Return the name of the grid as per the config .ini file.&lt;br /&gt;
|&lt;br /&gt;
| Moderate&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| string osGetGridLoginURI();&lt;br /&gt;
| Return the Login URI of the grid as per the config .ini file.&lt;br /&gt;
|&lt;br /&gt;
| Moderate&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| string osFormatString(string format, list params);&lt;br /&gt;
| Return the string with parameters substituted into it (format comes from .NET String.Format class) in . Parameters are specified positionally. Example: llOwnerSay(osFormatString(&amp;quot;{0}: pos is {1}&amp;quot;,[llGetName(), llGetPos()]));&lt;br /&gt;
|&lt;br /&gt;
| Low&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| list osMatchString(string source, string pattern);&lt;br /&gt;
| Return a list of matches for the pattern and its components inside the source string. The pattern is a regular expression with syntax defined by the .NET Regex class. Each match in the result is the string that matched and its position in the source.&lt;br /&gt;
|&lt;br /&gt;
| Low&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
[[Category:Users]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Second_Birthday</id>
		<title>Second Birthday</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Second_Birthday"/>
				<updated>2009-01-29T16:22:13Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: Added ScienceSim blog entry&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:OpenSim_2nd_Birthday_Banner.png]]&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
The consensus is that OpenSim was 'born' on Jan 29 2007, when Darren Guard (MW) made his prototypical c# 3D world server publicly available. Help us celebrate this joyous occasion! Read [[History]] for some recap of the early days.&lt;br /&gt;
&lt;br /&gt;
== Activities ==&lt;br /&gt;
Here you can add your activity, sorted by starting time GMT. Please supply at least basic information (when it starts, ends, what happens and how to get there). Also, if the activity takes place in a public hypergrid location, feel free to add link-region information so that others can link to your region.&lt;br /&gt;
&lt;br /&gt;
Consider announcing your party on the opensim-users mailing list.&lt;br /&gt;
&lt;br /&gt;
=== Jan 28 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|9:00pm&lt;br /&gt;
|1:00pm (PST)&lt;br /&gt;
|90 minutes&lt;br /&gt;
|Foolish Frost live from the Cornfield&lt;br /&gt;
|Rezzable Private Grid Alpha&lt;br /&gt;
|[http://rezzable.com/blog/vint-falken/opensim-2nd-birthday-celebration-foolish-frost-live-cornfield Instructions for existing &amp;amp; new accounts.]&lt;br /&gt;
|Non-hypergrid. (for now)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Jan 29 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|9:00pm (GMT)&lt;br /&gt;
|10:00pm (Local Time)&lt;br /&gt;
|3 hours&lt;br /&gt;
|Presentation of Cyberlandia (Italian) grid, ((((Welcome areas, outstanding building architecture tour and Dancing Party for everybody)))) &lt;br /&gt;
|www.cyberlandia.net www.opensimita.org&lt;br /&gt;
| &amp;quot;Born To Learn&amp;quot; and &amp;quot;Cyberlandia&amp;quot; sims. At entry point will find agenda and landmark givers. NB: due to severe instability problems we experienced in latest days we are not sure the event can take place without problems... The enthusiasm of the builders did provoke crashes on the land. If this is going to happen again this evening, please consider to use also the IRC channel on freenet (#cyberlandia) or going to web client http://www.cyberlandia.net/index.php?&amp;amp;page=smodul&amp;amp;id=17&amp;amp;btn=17 . When we will find the origin of the inconsistencies and solve the problems (probably posting some mantis), we will reschedule the presentation again. People interested in the Italian Cyberlandia project can also try to join the http://tinyurl.com/opensimita skype channel where people is connected during European day and evening/night.&lt;br /&gt;
|[[Hypergrid|grid.cyberlandia.net:8002]]&lt;br /&gt;
|-&lt;br /&gt;
|20:00pm (GMT)&lt;br /&gt;
|21:00pm (Local Time)&lt;br /&gt;
|2+ hours&lt;br /&gt;
|Game over for SL - Dark musix party, lottery and more. switch to night before enterering.&lt;br /&gt;
|www.schwarze-welle.de www.osgrid.org&lt;br /&gt;
| SCHWARZE WELT and surounding regions in osgrid&lt;br /&gt;
|[[Hypergrid|87.230.89.74:9000]]&lt;br /&gt;
|-&lt;br /&gt;
|14:00pm   (GMT)&lt;br /&gt;
|6:00am (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Introduction to Building - learn to build in OpenSim&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|-&lt;br /&gt;
|21:00pm   (GMT)&lt;br /&gt;
|13:00pm (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Introduction to Building - repeated for west coast and those who could not make it to the earlier class&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|-&lt;br /&gt;
|20:15pm   (GMT)&lt;br /&gt;
|21:15pm   (UTC+1) (France time)&lt;br /&gt;
|2 hours&lt;br /&gt;
|Live Concert by Bell Clellon (1 hour)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OpenMusic, OpenMinds (1 hour)&lt;br /&gt;
|New World Grid&lt;br /&gt;
* English : http://www.newworldgrid.com/lang/en-us/register&lt;br /&gt;
* Français : http://www.newworldgrid.com/lang/fr/register&lt;br /&gt;
| Events will take place at the Sunshine region. Prefer login to Welcome or Faelwen region to avoid avatar overload. You will redirected there ;)&lt;br /&gt;
&lt;br /&gt;
Two events :&lt;br /&gt;
* First, a live concert by Bell Clellon (about 1 hour)&lt;br /&gt;
* Second, a &amp;quot;OpenMusic, OpenMinds&amp;quot; mix party : broadcasting of Creative Commons music from Jamendo.com artists. OpenSim is Open, let the music be it too :D&lt;br /&gt;
&lt;br /&gt;
Blog : http://www.newworldgrid.com/os2b (EN/FR)&lt;br /&gt;
|No hypergrid access yet :D&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Jan 30 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|21:00pm   (GMT)&lt;br /&gt;
|13:00pm (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Particle Madness - learn to make your own particle effects&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|-&lt;br /&gt;
|22:00pm   (GMT)&lt;br /&gt;
|14:00pm (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|1939 World's Fair weekly meeting, 22:00-23:00 UTC - anyone interested in learning more and possibly participating in the reconstruction project are more than welcome to come along! &lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| 39FairHQ sim &lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Jan 31 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|16:00pm   (GMT)&lt;br /&gt;
|8:00am (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Creating Prim Hair - learn to make your prim hair&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|-&lt;br /&gt;
|22:00pm   (GMT)&lt;br /&gt;
|14:00pm (PST)&lt;br /&gt;
|til late night&lt;br /&gt;
|Mega Fright Night - public domain movies streamed to Reactiongrid - sit in an old time car (drive in style) or pop a squat on a tomato and pitch tomatoes at the screen and scream. A real fun time and we are planning to keep this running all night long - among movies you will see Gila Monster, House on Haunted Hill, and many more&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| Tarzan sim - directions and more at Welcome sim entrance or just head to Tarzan sim and join in!&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Jan 31 - Feb 1 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|24:&lt;br /&gt;
|24: &lt;br /&gt;
|48 hours&lt;br /&gt;
|Sailing Regatta - Live Music DJ's - Hypergrid - freebies&lt;br /&gt;
|[[OSGrid]]&lt;br /&gt;
|http://simzee.com/event.html&lt;br /&gt;
|OSGrid, M1 Rock (42, 96, 25) &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Feb 3 2009 ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!When? (GMT)&lt;br /&gt;
!When? (Local Time)&lt;br /&gt;
!Duration&lt;br /&gt;
!What?&lt;br /&gt;
!Where?&lt;br /&gt;
!How do I get there?&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
|-&lt;br /&gt;
|20:00pm   (GMT)&lt;br /&gt;
|12:00pm (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Photoshop CS3 for Textures&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|-&lt;br /&gt;
|21:00pm   (GMT)&lt;br /&gt;
|13:00pm (PST)&lt;br /&gt;
|1 hour&lt;br /&gt;
|Avatar Clothing Tutorial&lt;br /&gt;
|http://reactiongrid.com&lt;br /&gt;
| ReactionGrid Welcome Sim will have all markers and directions to which sims for each of the events.&lt;br /&gt;
|[[Hypergrid|http://gsquared.info:8008]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Demos and Exhibits ==&lt;br /&gt;
Here you can add your ongoing demo and/or interesting content. Please supply a brief description of the demo and/or content. Also, if the activity takes place in a public hypergrid location, feel free to add link-region information so that others can link to your region.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
!Title&lt;br /&gt;
!Description&lt;br /&gt;
!Location&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Urban Planning modules&lt;br /&gt;
|Traffic and pedestrian simulations in the UCI Grid, provided by [http://encitra.com/ Encitra].&lt;br /&gt;
|UCI Grid. Go to Gateway 7000 and use the teleporter for UCI Campus (1,1).  Or link to it directly, using the info on the right.&lt;br /&gt;
|ucigrid01.nacs.uci.edu:9000 (centered in the 8000's)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Metaverse Illuminations Gallery&lt;br /&gt;
|Large gallery of high-quality Second Life documentary photography&lt;br /&gt;
|OSGrid: Snoopies/21/15/521 (skybox) manual link: secondlife://Snoopies/21/15/521  &lt;br /&gt;
|(not sure!)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|German welcome area&lt;br /&gt;
|Informationen fuer deutsche Newbies im Osgrid, Freebies in Sharkland Hills, Mitbauer willkommen, Mietregionen&lt;br /&gt;
|OSGrid, Sharkland Tropical 3&lt;br /&gt;
|regionsDE.ralf-haifisch.biz:9000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|OpenSim Dutchies&lt;br /&gt;
|Mostly empty, but if you're lucky you catch me there for some information about interconnectivity between webinterface and virtual world, using wixtd and OpenSim&lt;br /&gt;
|OSN Grid&lt;br /&gt;
|os-networks:9000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Pseudospace - Ellis Island Welcome Center &amp;amp; Telehub&lt;br /&gt;
|Pop on by and enjoy a slice of open sourced birthday cake and punch in our lobby!  Feel free to look around and explore some of the different roleplay environments we're working on and help yourself to some freebies from our content library.  All sims on the grid are HyperGrid enabled so no need to worry about becoming stranded if you teleport off of Ellis Island. :)&lt;br /&gt;
|Pseudospace&lt;br /&gt;
|ellis.pseudospace.net:9000 &lt;br /&gt;
centered at 9000,9000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|OpenSimulator-Club&lt;br /&gt;
|Club (german language) for upcoming OpenSimulator and 3D-Internet activities. Founded to support the OpenSimulator 2nd birthday event.&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|http://www.talentraspel.de/index.php?option=com_content&amp;amp;view=article&amp;amp;id=53&amp;amp;Itemid=72&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|3D-Internet TV&lt;br /&gt;
|Web-TV channel (german language) covering news and developments for 3D-Internet activities. The OpenSimulator 2nd birthday event will be reported too.&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|http://www.talentraspel.de/index.php?option=com_wrapper&amp;amp;view=wrapper&amp;amp;Itemid=105&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Schwarze Welle&lt;br /&gt;
|Club and Shops (german/english) , 3D representation of www.schwarze-welle.de dark music radio. every monday german osgrid meeting 20:00 at next region SCHWARZE WELT&lt;br /&gt;
|OSGrid, SCHWARZE WELT&lt;br /&gt;
|87.230.89.74:9000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Open Vue&lt;br /&gt;
|Virtual University of Edinburgh on Opensim hosted on the Virtual AIAI Grid&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|http://vue.ed.ac.uk/openvue/&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|Folk Cate Delta&lt;br /&gt;
|Edy Rau's Folk Cafe(german/english) , every thursday 1 to 2 hours live musicans. 20 MET (11 PST)&lt;br /&gt;
|Grid4Us, Folk Cafe Delta&lt;br /&gt;
|http://grid4us.net:9020  (centered to 8500, 8500)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
'''|Sim-OnDemand'''''Italic text''&lt;br /&gt;
|Virtual world Abundance. Use robust Amazon EC2 infrastructure to run OpenSim server. GUI based EC2 launcher( No need to know EC2 API). Pay only for what you use. Very useful for occasional and experimentation with OpenSim. &lt;br /&gt;
|&lt;br /&gt;
|http://simondemand.ec29.com/index.html&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Blog Entries ==&lt;br /&gt;
Keep a list of the 2nd Birthday Blog Entries here:&lt;br /&gt;
* [http://opensimulator.info/article.php/Opensim-Les-anniversaires Happy 2nd birthday Opensimulator]&lt;br /&gt;
* [http://www.cybertechnews.org/?p=529 CyberTech News blog post]&lt;br /&gt;
* [http://xyzzyxyzzy.net/2009/01/29/happy-2nd-birthday-opensim/ happy 2nd birthday opensim (xyzzyxyzzy.net)]&lt;br /&gt;
* [http://blogs.intel.com/research/2009/01/sciencesim.php ScienceSim on Research@Intel]&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
=== Hypergrid Bridges ===&lt;br /&gt;
&lt;br /&gt;
To bridge between grids in the 1000's and grids in the 10,000's, you can use 2 gateways in the UCI Grid:&lt;br /&gt;
&lt;br /&gt;
* Gateway 3000, placed in position 3,000 3,000: ucigrid04.nacs.uci.edu 9003&lt;br /&gt;
* Gateway 7000, placed in position 7,000 7,000: ucigrid04.nacs.uci.edu 9007&lt;br /&gt;
&lt;br /&gt;
=== Banners ===&lt;br /&gt;
This banner is suitable for inclusion on your own web page, in blogs et c:&lt;br /&gt;
&lt;br /&gt;
[[Image:OpenSim_2nd_Birthday_Banner.png]]&lt;br /&gt;
&lt;br /&gt;
(Courtesy [http://www.vintfalken.com Vint Falken])&lt;br /&gt;
&lt;br /&gt;
=== Invitation Card ===&lt;br /&gt;
This image is suitable for creating your own invitation notecards:&lt;br /&gt;
&lt;br /&gt;
[[Image:OpenSim_Second_Birthday_Note.png]]&lt;br /&gt;
&lt;br /&gt;
(Courtesy [http://www.vintfalken.com Vint Falken])&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Public_Hypergrid_Nodes</id>
		<title>Public Hypergrid Nodes</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Public_Hypergrid_Nodes"/>
				<updated>2009-01-28T07:26:18Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of hypergrid-ready nodes that you can use for testing your installation and for linking your world. Please add your public node here if you wish to help build a web of opensims!&lt;br /&gt;
&lt;br /&gt;
For the time being, and until the security concerns are addressed, we advise you to be careful about who you link to. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
![[Hypergrid|link-region server and port]]&lt;br /&gt;
!Organization&lt;br /&gt;
!Description&lt;br /&gt;
!Grid Location&lt;br /&gt;
|-&lt;br /&gt;
|'''osl2.nac.uci.edu 9006'''&lt;br /&gt;
|University of California, Irvine&lt;br /&gt;
|The &amp;quot;UCI Welcome&amp;quot; region connected to OSGrid. It is run by Diva (Crista Lopes) on a machine owned by the University of California, Irvine. You can link to it as a way to link to OSGrid.&lt;br /&gt;
|OSGrid is centered at 10,000, 10,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''osl3.nac.uci.edu 9000'''&lt;br /&gt;
|University of California, Irvine&lt;br /&gt;
|The &amp;quot;UC Irvine&amp;quot; region connected to OSGrid, neighboring Wright Plaza. You can link to it as a way to link to OSGrid.&lt;br /&gt;
|OSGrid is centered at 10,000, 10,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''ucigrid02.nacs.uci.edu 9000'''&lt;br /&gt;
|University of California, Irvine&lt;br /&gt;
|The UCI Grid&lt;br /&gt;
|UCIGrid is centered at 8,888, 8,888&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''ucigrid04.nacs.uci.edu 9003'''&lt;br /&gt;
|University of California, Irvine&lt;br /&gt;
|The UCI Grid, region &amp;quot;Gateway 3000&amp;quot;. Link your lower-1,000's grid to this node in order to bridge to grids in the 10,000's.&lt;br /&gt;
|This node is positioned at 3,000, 3,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''ucigrid04.nacs.uci.edu 9007'''&lt;br /&gt;
|University of California, Irvine&lt;br /&gt;
|The UCI Grid, region &amp;quot;Gateway 7000&amp;quot;. Link your 10,000's grid to this node in order to bridge to grids in the lower-1,000's.&lt;br /&gt;
|This node is positioned at 7,000, 7,000. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''grid.cyberlandia.net 9000'''&lt;br /&gt;
|Cyberlandia&lt;br /&gt;
|The &amp;quot;Cyberlandia Gw&amp;quot; region. http://www.cyberlandia.net Metaverso italiano 3D, more to 250 region and 1000 users. You can link to it as a way to link to Cyberlandia. &lt;br /&gt;
|Cyberlandia is centered at ???&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''hypergrid.cyberlandia.net 9000'''&lt;br /&gt;
|Cyberlandia &lt;br /&gt;
|The &amp;quot;Osgrid Gw&amp;quot; region connected to Cyberlandia grid http://www.cyberlandia.net. Search on map &amp;quot;Cyberlandia grid&amp;quot; You can link to it as a way to link to OSGrid.  &lt;br /&gt;
|OSGrid is centered at 10,000, 10,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''regionsde.ralf-haifisch.biz 9045'''&lt;br /&gt;
|Ralf Haifisch on osgrid&lt;br /&gt;
|The &amp;quot;Sharkland Tropical&amp;quot; region connected to OSGrid. German welcome aerea, Freebie aerea, region rental, pretty tropical regions  &lt;br /&gt;
|Centered at 10000,10000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''joomla-italia.net 9000'''&lt;br /&gt;
|Social Network Italia&lt;br /&gt;
|The &amp;quot;SNI City&amp;quot; region connected to SNI (Social Network Italia) grid http://www.opensim-italia.net. This grid is connected with Osgrid,Collateral World,Francogrid and Darwin  &lt;br /&gt;
|Centered at ???&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''collateral.opensim-italia.net 9000'''&lt;br /&gt;
|Part of Social Network Italia&lt;br /&gt;
|Collateral World &lt;br /&gt;
|Centered at ???&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''88.191.79.199 9050'''&lt;br /&gt;
|Francogrid&lt;br /&gt;
|Francogrid node, connected to &amp;quot;City&amp;quot;, behind the welcome land of Francogrid &amp;quot;Orion&amp;quot; &lt;br /&gt;
|Centered at 1000 1000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''94.23.8.158 9999'''&lt;br /&gt;
|Le Monde de Darwin&lt;br /&gt;
|The Lost World of Darwin http://www.LeMondedeDarwin.com. [[Image:hypergrid.jpg|200px]]&lt;br /&gt;
|Centered at ???&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''grid.k-grid.com 9000'''&lt;br /&gt;
|K-Grid&lt;br /&gt;
|The Kool grid for the Kool KidZ . Feel free to visit us. The main Gateway is located at 3700,3700 so take that in account before any HyperJump &lt;br /&gt;
|This node is located at 3700,3700&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''metropolis.hypergrid.org 9000'''&lt;br /&gt;
|METROPOLIS-Grid&lt;br /&gt;
|The Region &amp;quot;Center-World&amp;quot; (at 1000:1000) connected to the METROPOLIS-Grid http://metropolis.hypergrid.org . German Grid with a lot of free Content and free SIM-hosting. Connected via HG to the most of the Grids listed here &lt;br /&gt;
|Centered at 1000,1000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''ascent.bluewallgroup.com 9910'''&lt;br /&gt;
|BlueWall Group&lt;br /&gt;
|This region is in a good proximity @ (6000,6000) for intermediate jumps to OSGrid from grids in the (2000,2000) range, or any region within 4096 units. [[Image:Hypernaut 001.png|150px|none|thumb|Get your Hypernaut here :)]]&lt;br /&gt;
|Centered at 6000,6000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''sim.thestudyofracialism.org 9000'''&lt;br /&gt;
|Backintyme Publishing&lt;br /&gt;
|TSOR1 is a stand-alone sim owned by Backintyme Publishing. It connects to most of the other downrange sites listed here. The sim is intended for an SL study/discussion group's eventual migration from SL to OS.&lt;br /&gt;
|Centered at 4000,4000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''pc.backintyme.com 9100'''&lt;br /&gt;
|Backintyme Publishing&lt;br /&gt;
|TSOR2 is a small teleport relay island, also owned by Backintyme Publishing, intended for jumps to the vicinity of OSGrid. It is linked to most of the uprange sites listed here.&lt;br /&gt;
|Centered at 8000,8000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''24.248.172.208 9003'''&lt;br /&gt;
|'''MyOpenGrid'''&lt;br /&gt;
|Myopengrid is connected to osl2.nac.uci.edu &amp;quot;Osgrid Gateway&amp;quot; and 88.191.79.199 9050 &amp;quot;Franco Grid&amp;quot;&lt;br /&gt;
|Centered at 7000,7000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''cuonsim1.de 9300'''&lt;br /&gt;
|Cuon-Grid&lt;br /&gt;
|Cuon-Grid is a little grid and has some Main Sims with linux themes, server are in Germany. To login in to the grid use this http://sim-linuxmain.org:8081/CuonGrid/index.html. There are free sims for testing. &lt;br /&gt;
|Centered at 10,000, 10,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''metaversesims.net 9014'''&lt;br /&gt;
|Metaverse Sims&lt;br /&gt;
|Standalone mode - 6 regions - linked to several other grids. [[Image:Mtvs09010101.jpg|200px]]&lt;br /&gt;
|Centered at 9,000, 9,000&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''mecatreco.game-host.org 9002'''&lt;br /&gt;
|Villa Pelopes &lt;br /&gt;
|Two regions,one standalone server. Member of the [http://www.dmu.com Digital Media Universe], brazilian federation of independed hypergrided worlds: [[Image:Dmu.jpg|100px]]&lt;br /&gt;
| 1002 1002&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''ellis.pseudospace.net 9000'''&lt;br /&gt;
|Pseudospace Central Gateway &amp;amp; Welcome Center &lt;br /&gt;
|Pseudospace is a free to play, public access OpenSimulator grid created to provide role players with an immersive environment by which they may play, socialize, and build within.  This is a mature grid which may contain adult content and situations, only those who are 18 or older may enter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Please be advised, that we are currently under heavy construction. Feel free to look around, but mind the mess and the occasional flying prims! If you have any questions or concerns please feel free to email john(at)pseudospace(dot)net.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All user content such as skins, attachments, textures, etc. are provided for free using a share and share alike, create for the sake of creativity methodology.  All such assets are kept within the content library on Ellis Island and are freely copyable / distributable unless the &amp;quot;No Transfer&amp;quot; option is enabled which simply means that the asset may not be copied off of the grid.  Individual contributions to the grid's content library are greatly welcomed and may be done so by leaving a copyable box containing your contribution on one of the shelves located inside the Ellis Library.&lt;br /&gt;
&lt;br /&gt;
| 9000 9000&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|'''grid4us.net 9020'''&lt;br /&gt;
|Grid4Us&lt;br /&gt;
|German Grid that is linked to OSGrid and Francogrid.&lt;br /&gt;
|Centered at 8500,8500&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''gotz.ath.cx  9002'''&lt;br /&gt;
|Gotz&lt;br /&gt;
|One region,one standalone server. Visits: 9:00 PST -&amp;gt; 19:00 PST. Member of the &lt;br /&gt;
[http://www.dmu.com Digital Media Universe] , brazilian federation of independent hypergrided worlds:[[Image:Dmu.jpg|100px]]&lt;br /&gt;
| 1002 1002&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''villapileque.game-host.org  9002'''&lt;br /&gt;
|Villa Pileque&lt;br /&gt;
|One region,one standalone server.   Member of the &lt;br /&gt;
[http://www.dmu.com Digital Media Universe] , brazilian federation of independent hypergrided worlds:[[Image:Dmu.jpg|100px]]&lt;br /&gt;
| 1002 1002&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|'''peak.sciencesim.com 9001'''&lt;br /&gt;
|ScienceSim&lt;br /&gt;
|[http://www.sciencesim.com/ ScienceSim] is a virtual world created for the high performance computing community for scientific visualizations, a number of interesting real world terrains (Mt St Helens and Yellowstone Park) and some astronomical simulations. And some useful, BSD-licensed content.&lt;br /&gt;
| Centered at 10000,10000&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	<entry>
		<id>http://opensimulator.org/wiki/Grid_List/ScienceSim</id>
		<title>Grid List/ScienceSim</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/wiki/Grid_List/ScienceSim"/>
				<updated>2009-01-28T07:01:52Z</updated>
		
		<summary type="html">&lt;p&gt;Cmickeyb: New page: &amp;lt;table border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;   &amp;lt;tr&amp;gt;     &amp;lt;td&amp;gt;Name:&amp;lt;/td&amp;gt;     &amp;lt;td&amp;gt;ScienceSim&amp;lt;/td&amp;gt;   &amp;lt;/tr&amp;gt;   &amp;lt;tr&amp;gt;     &amp;lt;td&amp;gt;Website:&amp;lt;/td&amp;gt;     &amp;lt;td&amp;gt;http://www.sciencesim.com&amp;lt;/td&amp;gt;   &amp;lt;/tr&amp;gt;   &amp;lt;...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Name:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;ScienceSim&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Website:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;http://www.sciencesim.com&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Login URI:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;http://island.sciencesim.com:8002/&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Wiki/Forum:&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;http://www.sciencesim.com/wiki&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Approx # Regions&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;~25&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Approx # Users&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;~30&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;Logins/day&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;10&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ScienceSim is a virtual world for the high performance computing community. The expectation is that scientists will create collaborative visualizations driven by various HPC simulations. ScienceSim is maintained by the IEEE/ACM SuperComputing conference committee.&lt;/div&gt;</summary>
		<author><name>Cmickeyb</name></author>	</entry>

	</feed>