User:Void Singer/Region Stats
Region Stats
What is it?
Regions Stats is an open source extension for Teacup designed as a demo of pulling live data from within SL into an html page. It additionally demonstrates the use of inline scripting for .tsp files, as well a method by which live data pages can overcome the internal browsers caching of duplicate page requests therein.
Code
Region Stats
- Save in a MONO script named "Region Stats"
<lsl>/*( Region Stats )*/
string gStrNom = "Region Stats.tsp"; //-- file name that we serve data to //-- we insert the page name & request key later for the refresh to override same page cahing in the internal browser string gStrPg0 = "v0='<script>RS=setTimeout(\"u1(\\'";
string gStrPg1 = "\\')\", 60000 );</script>\\n<a href=\"index.tsp\" onClick=\"clearTimeout(RS);\">Return to index</a>?
\\n\\n"; string gStrPg2 = "string gStrNfo; //-- stores static Region information integer gIntFlg; //-- the current region flags string gStrFlg; //-- stores Region flags (updated as needed only) string gStrTod; //-- Stores Region Time of Day (updates live if Fixed Sun == false)
key gKeyQry; //-- Dataserver Query key integer gBooRdy; //-- Controls availability advertisement
uGetTod( vector vPosSun ){ //-- grabs Region apparent Time of Day (slightly inaccurate) vPosSun = llVecNorm( <vPosSun.x, 0.0, vPosSun.z> ); integer vIntTod = (integer)(86400.0 - (llAtan2( vPosSun.x, vPosSun.z ) * RAD_TO_DEG + 180) * 240.0); gStrTod = (string)(vIntTod / 3600) + ":" + llGetSubString( "0" + (string)(vIntTod % 3600 / 60), -2, -1 ) + ":" + llGetSubString( "0" + (string)(vIntTod % 60), -2, -1 ) + ""; }
default{ state_entry(){ //-- make the page seem unavailable while we refresh our static data llMessageLinked( LINK_SET, 600, gStrNom, NULL_KEY ); gStrNfo = //-- Start building static info
"Pre-calculated Data\\nRegion Name:" + llGetRegionName() + "\\n"; uGetTod( llGetSunDirection() ); //-- set once to make logic faster later gKeyQry = llRequestSimulatorData( llGetRegionName(), DATA_SIM_RATING ); } dataserver( key vKeyQID, string vStrDta ){ if (gKeyQry == vKeyQID){ //-- continue building static info gStrNfo += "Region Rating:" + //-- this is one way to get unknown ratings noticed =XllList2String( ["General", "Moderate", "Adult", "XXX Pr0nland"], llListFindList( ["PG", "MATURE", "ADULT", "UNKNOWN"], [vStrDta] ) ) +
"\\nRegion Location:(";vector vPosTmp = llGetRegionCorner(); gStrNfo += (string)((integer)vPosTmp.x) + ", " +
(string)((integer)vPosTmp.y) + ")\\nServer Name:" + llGetSimulatorHostname() + "\\nServer Channel:" + llGetEnv( "sim_channel" ) + "\\nServer Version:";list vLstTmp = llParseString2List( llGetEnv( "sim_version" ), ["."], [] ); gStrNfo += //-- version number contains build date, sneaky huh?
llDumpList2String( vLstTmp, "." ) + "\\nServer Build Date:" +llList2String( ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ~-llList2Integer( vLstTmp, 1 ) ) +
" " + llList2String( vLstTmp, 2 ) + ", 20" + llList2String( vLstTmp, 0 ) + "\\n"; gBooRdy = TRUE; //-- this variable is only used to readvertise to Saucer when it starts llMessageLinked( LINK_SET, 601, gStrNom, NULL_KEY ); } } link_message( integer vIntSrc, integer vIntDta, string vStrDta, key vKeyDta ){ if (418 == vIntDta){ if (vKeyDta){ if (gStrNom == llList2String( llParseStringKeepNulls( vStrDta, ["?"], [] ), 0 )){ if (gIntFlg != vIntDta = llGetRegionFlags()){ gIntFlg = vIntDta; //-- only (re)built if flags change or at first request list vLstFlg = ["Y", "N"]; //-- need to check this is better for mono lists than inline gStrFlg = "Region Flags\\nDamage Enabled?" +llList2String( vLstFlg, !(0x00000001 & gIntFlg) ) +
"\\n†Allow Landmark?" +llList2String( vLstFlg, !(0x00000002 & gIntFlg) ) +
"\\n†Allow Set Home?" +llList2String( vLstFlg, !(0x00000004 & gIntFlg) ) + /*//-- I don't think this is used
"\\n†Reset Home On Teleport?" +llList2String( vLstFlg, !(0x00000008 & gIntFlg) ) + */
"\\nFixed Sun?" +llList2String( vLstFlg, !(0x00000010 & gIntFlg) ) + /*//-- Unused, taxes were abolished for SL ages ago
"\\n†Tax Free?" +llList2String( vLstFlg, !(0x00000020 & gIntFlg) ) + */
"\\nBlock Terraform?" +llList2String( vLstFlg, !(0x00000040 & gIntFlg) ) +
"\\n†Block Land Resell?" +llList2String( vLstFlg, !(0x00000080 & gIntFlg) ) +
"\\nIs Sandbox?" +llList2String( vLstFlg, !(0x00000100 & gIntFlg) ) + /*//-- I don't think any of these are used
"\\n‡Null Layer?" +llList2String( vLstFlg, !(0x00000200 & gIntFlg) ) +
"\\n‡Allow Land Xfer?" +llList2String( vLstFlg, !(0x00000400 & gIntFlg) ) +
"\\n‡Skip Update Interest List?" +llList2String( vLstFlg, !(0x00000800 & gIntFlg) ) + */
"\\nDisable Collisions?" +llList2String( vLstFlg, !(0x00001000 & gIntFlg) ) +
"\\n†Skip Scripts?" +llList2String( vLstFlg, !(0x00002000 & gIntFlg) ) +
"\\nDisable Physics?" +llList2String( vLstFlg, !(0x00004000 & gIntFlg) ) +
"\\n†Externally Visible?" +llList2String( vLstFlg, !(0x00008000 & gIntFlg) ) + /*//-- Encroachment code isn't used(yet), Dwell was removed ages ago
"\\n†Allow Return Encroaching?" +llList2String( vLstFlg, !(0x00010000 & gIntFlg) ) +
"\\n†Allow Return Enchroching(Estate)?" +llList2String( vLstFlg, !(0x00020000 & gIntFlg) ) +
"\\n†Block Dwell?" +llList2String( vLstFlg, !(0x00040000 & gIntFlg) ) + */
"\\nBlock Fly?" +llList2String( vLstFlg, !(0x00080000 & gIntFlg) ) +
"\\nAllow Direct TP?" +llList2String( vLstFlg, !(0x00100000 & gIntFlg) ) +
"\\n†Skip Scripts(Estate)?" +llList2String( vLstFlg, !(0x00200000 & gIntFlg) ) +
"\\nRestrict Push?" +llList2String( vLstFlg, !(0x00400000 & gIntFlg) ) +
"\\n†Deny Anonymous?" +llList2String( vLstFlg, !(0x00800000 & gIntFlg) ) + /*//-- I don't think these are used anymore, used to be for OI?
"\\n‡Deny Identified?" +llList2String( vLstFlg, !(0x01000000 & gIntFlg) ) +
"\\n‡Deny Transacted?" +llList2String( vLstFlg, !(0x02000000 & gIntFlg) ) + */
"\\n†Allow Parcel Changes?" +llList2String( vLstFlg, !(0x04000000 & gIntFlg) ) + /*//-- Prtty sure this is disabled
"\\n‡Abuse Email 2 Estate Owner?" +llList2String( vLstFlg, !(0x08000000 & gIntFlg) ) + */
"\\n†Allow Voice?" +llList2String( vLstFlg, !(0x10000000 & gIntFlg) ) +
"\\n†Block Parcel Search?" +llList2String( vLstFlg, !(0x20000000 & gIntFlg) ) +
"\\n†Deny Age unVerified?" +llList2String( vLstFlg, !(0x40000000 & gIntFlg) ) + /*//-- Pretty sure this is disabled as well since MONO went mainstream.
"\\n‡Skip Scripts(MONO)?" +llList2String( vLstFlg, !(0x80000000 & gIntFlg) ) + */
"\\n†=Does not have an LSL constant
‡=No longer exists in source code\\n";
} if (~gIntFlg & 0x00000010){ //-- don't update for fixed sun uGetTod( llGetSunDirection() ); } llMessageLinked( vIntSrc, 201, //-- Next Line: key insertion lets us override internal browser page caching for live refresh gStrPg0 + gStrNom + "?" + (string)vKeyDta + gStrPg1 + gStrNfo +
"Live Data\\nRegion Tod:" + gStrTod + " rST (24hr)\\nRegion FPS:" + (string)llGetRegionFPS() + "\\nTime Dilation:" + (string)llGetRegionTimeDilation() + "\\nAgent Count:" + (string)llGetRegionAgentCount() + "\\nShared Borders:" +(string)(!llEdgeOfWorld( <128.0, 128.0, 128.0>, < 0.0, 1.0, 0.0> ) + !llEdgeOfWorld( <128.0, 128.0, 128.0>, < 1.0, 0.0, 0.0> ) + !llEdgeOfWorld( <128.0, 128.0, 128.0>, < 0.0, -1.0, 0.0> ) + !llEdgeOfWorld( <128.0, 128.0, 128.0>, <-1.0, 0.0, 0.0> )) +
"\\n" + gStrFlg + gStrPg2, vKeyDta ); } }else if (NULL_KEY == vKeyDta && "" == vStrDta && gBooRdy){ //-- Saucer stared, let tell it we have a page. Realistically unneccessary llMessageLinked( vIntSrc, 601, gStrNom, NULL_KEY ); }//-- out page actualy serves in under a sec even on first request, but I wanted to demo the logic } } changed( integer vBitChg ){ if ((CHANGED_REGIONNotes
Compatible Servers, File Systems, and Extensions
- Teacup - SIP front end
- Saucer - Optional Fast 404 Extension for preventing long timeouts for missing/bad pages
- Tea Strainer - Optional Troubleshooting Monitor for checking messages being sent and received.
Known Bugs
- There is a vague posibility that an initial request could come in during the state_entry, before the dataserver fires. if this happens, the first display will not include some static data, subsequent auto-refreshes will eventually update this (usually on the next refresh)