SkidzPartz.com Scripting Notecard Server with a interpreted language
|

Who's Online

We have 33 guests online

Users Online

None

Help support us

Notecard Server with a interpreted language PDF Print E-mail
Second Life - Scripting
Written by Skidz Tweak   
Thursday, 30 July 2009 04:38





Have you had a chance to play with the new HTTPIn Yet? I have, and put together a great demo of its power for fun, and thought I would share it with all. Its a notecard server that allows you to request notecards, and that has an interpreted language built in. What this means is you can place some of what I call NSL (notecard scripting language) into the notecard to change what content is served up.
 
For Example:
I request the URL /Default?Version=1.0
I could place something anywhere in the notecard "Default" that would redirect the content to be returned to a specific line, like so:
[if ([@Version] > 0.9)] line 10

The if statement can support ==, >=, <=, >, <

It also can place query stings values passed into the notecard. For example, if I request the URL "Default?avatar_name=Skidz Tweak" and I had something like this in the notecard "Welcome [@avatar_name]" it would return "Welcome Skidz Tweak"

I really think the major potential for something like this, especially for changing configurations on the fly of a product. A Great example of something like this would be, a game. I wish I had time to make a kewl game with this . It could serve up all the content like.. tasks, and other options.

Limitations:
While this works with multiple request if you were going to use this on any kinda scale you would want to implement some load balancing somehow. This also suffers from all the other HTTPIn problems of the temporary URL. You would need to develop some kind of httpin registry for the URLs. And of course the notecard can not be read if there are object in it, like landmarks, or images. It also can only read the first 256 characters of each line.

Free free to use it in your products, but if you make any real improvements please send me a copy and I will try to keep it updated here.

//settings
string defaultPage = "default";

integer count;
string url;

list Response = [];
list RequestForm = [];
list Request = [];
list RequestPage = [];
list HTTPRequests = [];
list HTMLReadKey = [];
list HTMLReadLine = [];

string str_replace(string src, string from, string to)
{//replaces all occurrences of 'from' with 'to' in 'src'.
integer len = (~-(llStringLength(from)));
if(~len)
{
string  buffer = src;
integer b_pos = -1;
integer to_len = (~-(llStringLength(to)));
@loop;
integer to_pos = ~llSubStringIndex(buffer, from);
if(to_pos)
{
buffer = llGetSubString(src = llInsertString(llDeleteSubString(src, b_pos -= to_pos, b_pos + len), b_pos, to), (-~(b_pos += to_len)), 0x8000);
jump loop;
}
}
return src;
}

default
{
state_entry()
{
//Get the intial URL
llRequestURL();
}

http_request(key id, string method, string body)
{
if (method == URL_REQUEST_GRANTED)
{
//URL granted
llOwnerSay(body);
url = body;
return;
}
//getting the notecard name
string x_path_info = llGetHTTPHeader(id,"x-path-info");
//Trimming off the /
if (llGetSubString(x_path_info,0,0) == "/")
x_path_info = llGetSubString(x_path_info,1,-1);
//Setting the default page if no page was passed
if (x_path_info == "")
x_path_info = defaultPage;

//Check to see if the notecard exists. If it does not throw 404 Error
if (llGetInventoryType(x_path_info) != INVENTORY_NOTECARD)
{
llHTTPResponse(id,404,"The page " + x_path_info + " does not exists.");
return;
}

//adding these values to the list so they can be used in dataserver
RequestPage += [x_path_info];
Response += [""];
RequestForm += [body];
Request += [llGetHTTPHeader(id, "x-query-string")];
HTTPRequests += [id];
HTMLReadLine += [1];
HTMLReadKey += llGetNotecardLine(x_path_info,0);
}

changed(integer change)
{
if (CHANGED_REGION_START & change)
llRequestURL();
}

dataserver(key query_id, string data)
{
integer inQ = llListFindList(HTMLReadKey,  [query_id]);
if (inQ > -1)
{
if (data == EOF)
{
//Cleaning up
llHTTPResponse(llList2Key(HTTPRequests,inQ), 200, llList2String(Response,inQ));
Response = llListReplaceList(Response, [], inQ, inQ);
RequestForm = llListReplaceList(RequestForm, [], inQ, inQ);
Request = llListReplaceList(Request, [], inQ, inQ);
HTTPRequests = llListReplaceList(HTTPRequests, [], inQ, inQ);
HTMLReadLine = llListReplaceList(HTMLReadLine, [], inQ, inQ);
HTMLReadKey = llListReplaceList(HTMLReadKey, [], inQ, inQ);
RequestPage = llListReplaceList(RequestPage, [], inQ, inQ);
}
else
{
//reparse the query string and replace [@QUERYSTRING_NAME] with QUERYSTRINGVALUE
list tempRequest = llParseString2List(llList2String(Request,inQ), ["&"], []) + llParseString2List(llList2String(RequestForm,inQ), ["&"], []);
integer requestLength = llGetListLength(tempRequest);integer i = -1;
list formFields = [];
list formValues = [];
while(requestLength > ++i)
{
list tempRequestField = llParseString2List(llList2String(tempRequest,i), ["="], []);
formFields += llList2String(tempRequestField,0);
formValues += llList2String(tempRequestField,1);
data = str_replace(data, "[@" + llUnescapeURL(llList2String(tempRequestField,0)) + "]", llUnescapeURL(llList2String(tempRequestField,1)));
}

string raw = llToUpper(str_replace(data, " ",""));
//Checking to see if this line is an if statement
if (llGetSubString(raw,0,3) == "[IF(")
{
//parseing the if line for details
integer statement = FALSE;
integer close = llSubStringIndex(raw, ")]");
if (close > -1)
{
string test = llGetSubString(raw, 4, close - 1);
if (llSubStringIndex(test, "==") > -1)
{
list tempList = llParseString2List(test, ["=="], []);
if (llList2String(tempList,0) == llList2String(tempList,1))
statement = TRUE;
}
else if (llSubStringIndex(test, ">=") > -1)
{
list tempList = llParseString2List(test, [">="], []);
if (llList2Float(tempList,0) >= llList2Float(tempList,1))
statement = TRUE;
}
else if (llSubStringIndex(test, "<=") > -1)
{
list tempList = llParseString2List(test, ["<="], []);
if (llList2Float(tempList,0) <= llList2Float(tempList,1))
statement = TRUE;
}
else if (llSubStringIndex(test, ">") > -1)
{
list tempList = llParseString2List(test, [">"], []);
if (llList2Float(tempList,0) > llList2Float(tempList,1))
statement = TRUE;
}
else if (llSubStringIndex(test, "<") > -1)
{
list tempList = llParseString2List(test, ["<"], []);
if (llList2Float(tempList,0) < llList2Float(tempList,1))
statement = TRUE;
}
}
if (statement)
{
string toDo = llGetSubString(raw, close + 1, -1);
if (llSubStringIndex(toDo,"LINE=") == 1)
{
HTMLReadLine = llListReplaceList(HTMLReadLine, [llGetSubString(toDo,6,-1)], inQ, inQ);
}
}
data = "";
}
else
{
data += "\n";
}
//Reading the next line in the notecard
Response = llListReplaceList(Response, [llList2String(Response,inQ) + data], inQ, inQ);
HTMLReadKey = llListReplaceList(HTMLReadKey, [llGetNotecardLine(llList2String(RequestPage,inQ),llList2Integer(HTMLReadLine,inQ))],inQ,inQ);
HTMLReadLine = llListReplaceList(HTMLReadLine, [llList2Integer(HTMLReadLine,inQ) + 1], inQ, inQ);
}
}
}
}

Last Updated on Thursday, 30 July 2009 08:17
 

Comments  

 
0 #1 Skidz Tweak 2009-07-30 07:28
The formatting is terrible on the description part because the script is messing up the width... If you can't read everything you can head over to the forums where I posted it as well:

http://forums.secondlife.com/showthread.php?t=332625
 

Skidz Partz Shopping

Your cart is empty

Skidz Partz Blog RSS

Skidz Partz

SkidzPartz Login

Polls

Should the TMat 4.0 be made of Mesh? This does not mean it will support mesh, just made of mesh..
 

CB Workflows