Difference between revisions of "Dataserver API"
(New page: {{LSL Header}} Dataserver Framework ---- Introduction: the most common problem i find is people asking about dataservers, reading from notecards to bypass variables within a notecard so...) |
m (→Notecard: Replaced <source> with <syntaxhighlight>, using INI formatting) |
||
(10 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header}} | {{LSL Header}} | ||
{{RightToc}} | |||
=Dataserver Framework= | |||
===Introduction=== | |||
- | A common problem in SL is reading and parsing notecards by script. One application for this is so a script can be distributed as no-mod but still be configurable. | ||
The below framework demonstrates how to setup such an interface with very little work to retool. | |||
Main Script | The default state reads the notecard and when it is done it activates the configuration state. | ||
< | |||
===Testimonial=== | |||
The most common problem I find is people asking about dataservers, reading from notecards to bypass variables within a notecard so you can release your script as nomod. | |||
So I setup a simple system that I use time and time again that can be reused in any project. | |||
The class itself is state based meaning the default state reads the notecard and then starts another state when the notecard is read and ready to use I explain this further below. | |||
==Main Script== | |||
<syntaxhighlight lang="lsl2"> | |||
string notecard_name = "configuration"; // name of notecard goes here | string notecard_name = "configuration"; // name of notecard goes here | ||
key queryhandle; // to | // internals | ||
integer DEBUG = FALSE; | |||
integer line; | |||
key queryhandle; // to separate Dataserver requests | |||
key notecarduuid; | |||
// | init() | ||
{ | |||
queryhandle = llGetNotecardLine(notecard_name, line = 0);// request line | |||
notecarduuid = llGetInventoryKey(notecard_name); | |||
} | |||
// Config data loaded from notecard, with some sane defaults | // Config data loaded from notecard, with some sane defaults | ||
Line 28: | Line 42: | ||
// We want to reload channel notecard if it changed | // We want to reload channel notecard if it changed | ||
if (change & CHANGED_INVENTORY) | if (change & CHANGED_INVENTORY) | ||
if(notecarduuid != llGetInventoryKey(notecard_name)) | |||
init(); | |||
} | } | ||
state_entry() | state_entry() | ||
{ | { | ||
init(); | |||
} | } | ||
dataserver(key query_id, string data) { | dataserver(key query_id, string data) | ||
if (query_id == queryhandle) { | { | ||
if (query_id == queryhandle) | |||
if (data != EOF) { | { | ||
if (data != EOF) | |||
{ // not at the end of the notecard | |||
// yay! Parsing time | // yay! Parsing time | ||
// | |||
if (llGetSubString (data, 0, 0) != "#" | // pesky whitespace | ||
data = llStringTrim(data, STRING_TRIM_HEAD); | |||
// is it a comment? | |||
if (llGetSubString (data, 0, 0) != "#") | |||
{ | { | ||
integer s = llSubStringIndex(data, "="); | |||
string token = llToLower (llStringTrim ( | if(~s)//does it have an "=" in it? | ||
{ | |||
string token = llToLower(llStringTrim(llDeleteSubString(data, s, -1), STRING_TRIM)); | |||
data = llStringTrim(llDeleteSubString(data, 0, s), STRING_TRIM); | |||
//Insert your token parsers here. | |||
if (token == "email_address") | |||
email_address = data; | |||
else if (token == "channel") | |||
channel = (integer)data; | |||
} | |||
} | } | ||
queryhandle = llGetNotecardLine(notecard_name, line); | queryhandle = llGetNotecardLine(notecard_name, ++line); | ||
if(DEBUG) llOwnerSay("Notecard Data: " + data); | |||
} else { | } | ||
if ( | else | ||
{ | |||
state configuration ; | if(DEBUG) llOwnerSay("Done Reading Notecard"); | ||
state configuration ; | |||
} | } | ||
} | } | ||
} | } | ||
} | } | ||
Line 70: | Line 94: | ||
{ | { | ||
state_entry() | |||
{ | |||
llListen(channel, "", "", ""); | |||
llShout(0, "Channel set to " + (string)channel); | |||
llShout(0, "Email set to " + (string)email_address); | |||
} | |||
} | } | ||
</ | </syntaxhighlight> | ||
==Notecard== | |||
< | <syntaxhighlight lang="ini"> | ||
# This is the configuration file | # This is the configuration file | ||
channel = 1000 | channel = 1000 | ||
Line 86: | Line 110: | ||
# end | # end | ||
</ | </syntaxhighlight> | ||
Lines that start with "#" are comments. | |||
==How It Works== | |||
the | The [[default]] [[state]] reads and parses all the lines in the notecard. As it reads the notecard it overwrites the default values with the values in the notecard. More specifically after each line has been validated and tokenized, the token is checked against supported tokens. If the token is supported the specific parser for the token is called, in the above example it is just a simple convert and copy. | ||
For technical support, requests, etc., use the Search under the Groups Tab and search for | For technical support, requests, etc., use the Search under the Groups Tab and search for Dazzle Software | ||
If you have any problems getting this script to work either contact me in-world [https://wiki.secondlife.com/wiki/User:Revolution_Perenti Revolution Perenti] | |||
Or visit our free scripts at our LSL scripts [http://www.dazzlesoftware.org www.dazzlesoftware.org] Secondlife Open Source Section on Tutorials. | |||
[http:// | Latest version always available on [https://marketplace.secondlife.com/p/Dazzle-Software-DataServer-API/374436 Marketplace] or [http://maps.secondlife.com/secondlife/Wyrd/230/83/97 Dazzle Software via Wyrd] | ||
{{LSLC|Library}}{{LSLC|Examples}} |
Latest revision as of 16:55, 9 February 2023
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Dataserver Framework
Introduction
A common problem in SL is reading and parsing notecards by script. One application for this is so a script can be distributed as no-mod but still be configurable.
The below framework demonstrates how to setup such an interface with very little work to retool.
The default state reads the notecard and when it is done it activates the configuration state.
Testimonial
The most common problem I find is people asking about dataservers, reading from notecards to bypass variables within a notecard so you can release your script as nomod. So I setup a simple system that I use time and time again that can be reused in any project. The class itself is state based meaning the default state reads the notecard and then starts another state when the notecard is read and ready to use I explain this further below.
Main Script
string notecard_name = "configuration"; // name of notecard goes here
// internals
integer DEBUG = FALSE;
integer line;
key queryhandle; // to separate Dataserver requests
key notecarduuid;
init()
{
queryhandle = llGetNotecardLine(notecard_name, line = 0);// request line
notecarduuid = llGetInventoryKey(notecard_name);
}
// Config data loaded from notecard, with some sane defaults
integer channel = 1000;
string email_address = "revolution.perenti@skidzpartz.com";
default
{
changed(integer change)
{
// We want to reload channel notecard if it changed
if (change & CHANGED_INVENTORY)
if(notecarduuid != llGetInventoryKey(notecard_name))
init();
}
state_entry()
{
init();
}
dataserver(key query_id, string data)
{
if (query_id == queryhandle)
{
if (data != EOF)
{ // not at the end of the notecard
// yay! Parsing time
// pesky whitespace
data = llStringTrim(data, STRING_TRIM_HEAD);
// is it a comment?
if (llGetSubString (data, 0, 0) != "#")
{
integer s = llSubStringIndex(data, "=");
if(~s)//does it have an "=" in it?
{
string token = llToLower(llStringTrim(llDeleteSubString(data, s, -1), STRING_TRIM));
data = llStringTrim(llDeleteSubString(data, 0, s), STRING_TRIM);
//Insert your token parsers here.
if (token == "email_address")
email_address = data;
else if (token == "channel")
channel = (integer)data;
}
}
queryhandle = llGetNotecardLine(notecard_name, ++line);
if(DEBUG) llOwnerSay("Notecard Data: " + data);
}
else
{
if(DEBUG) llOwnerSay("Done Reading Notecard");
state configuration ;
}
}
}
}
state configuration
{
state_entry()
{
llListen(channel, "", "", "");
llShout(0, "Channel set to " + (string)channel);
llShout(0, "Email set to " + (string)email_address);
}
}
Notecard
# This is the configuration file
channel = 1000
email_address = phoenixcms@hotmail.co.uk
# end
Lines that start with "#" are comments.
How It Works
The default state reads and parses all the lines in the notecard. As it reads the notecard it overwrites the default values with the values in the notecard. More specifically after each line has been validated and tokenized, the token is checked against supported tokens. If the token is supported the specific parser for the token is called, in the above example it is just a simple convert and copy.
For technical support, requests, etc., use the Search under the Groups Tab and search for Dazzle Software
If you have any problems getting this script to work either contact me in-world Revolution Perenti Or visit our free scripts at our LSL scripts www.dazzlesoftware.org Secondlife Open Source Section on Tutorials. Latest version always available on Marketplace or Dazzle Software via Wyrd