2016-07-08

Parcel Settings Checker

This is something I wrote earlier this year, and which I wish I'd thought to write a lot sooner. On Raven Park there's a handful of plots that are for rent and, as part of those rentals, there's a few rules to keep things safe and clean. Two big ones are that you don't have public build turned on, and that you also don't have ban lines (security tools are fine -- but no ban lines please, they're ugly!). So, of course, every so often, I had to fly around the region and check settings.

Which was a silly thing to do when I could have a script do the job for me! It was quick and easy to write and I thought I should finally publish it here in case it was useful to someone:

//////////////////////////////////////////////////////////////////////
// Z&A Parcel Checker
// By Antony Fairport
//
// Z&A Checker - Check that parcels are always using the right
// settings.
//
// Revision history:
// ------------------------------------------------------------
//
// 2016-02-05
// Initial revision.
//////////////////////////////////////////////////////////////////////
// Constants.
string EMAIL_REPORT_TO = "report@example.com";
//////////////////////////////////////////////////////////////////////
// Globals
list g_lParcels;
//////////////////////////////////////////////////////////////////////
// Have we seen the given parcel?
integer SeenParcel( key kID )
{
return llListFindList( g_lParcels, [ kID ] ) != -1;
}
//////////////////////////////////////////////////////////////////////
// Remember the given parcel.
RememberParcel( key kID )
{
g_lParcels += kID;
}
//////////////////////////////////////////////////////////////////////
// Report on what we can find at the parcel at the given location.
string ReportOnParcelAt( integer x, integer y )
{
list lIssues;
integer iFlags = llGetParcelFlags( < x, y, 0.0 > );
if ( iFlags & PARCEL_FLAG_ALLOW_CREATE_OBJECTS )
{
lIssues += "Public Build";
}
if ( ( iFlags & PARCEL_FLAG_USE_ACCESS_GROUP ) || ( iFlags & PARCEL_FLAG_USE_ACCESS_LIST ) )
{
lIssues += "Ban lines";
}
if ( lIssues == [] )
{
lIssues += "All good";
}
return llList2CSV( lIssues );
}
//////////////////////////////////////////////////////////////////////
// Check the parcel at the given location on the region.
string CheckParcelAt( integer x, integer y )
{
// Get the ID and name of the parcel at the given spit.
list lDetails = llGetParcelDetails( < x, y, 0.0 >, [
PARCEL_DETAILS_ID, PARCEL_DETAILS_NAME
] );
// Pull out the parts.
key kID = llList2Key( lDetails, 0 );
string sName = llList2Key( lDetails, 1 );
// Bit of progress feedback.
llSetText( "Checking\n" + ( (string) x) + "," + ( (string) y ) + "\n" + sName, < 1.0, 1.0, 1.0 >, 1.0 );
// Start the report.
string sReport;
// If we've not seen that parcel yet...
if ( !SeenParcel( kID ) )
{
sReport += sName + ": " + ReportOnParcelAt( x, y ) + "\n";
RememberParcel( kID );
}
return sReport;
}
//////////////////////////////////////////////////////////////////////
// Check all parcels on a region.
string CheckParcels()
{
// Step size while walking and looking for plots.
integer PLOT_STEP = 4;
// Forget all known parcels.
g_lParcels = [];
// Start the report.
string sReport;
// Roam over the whole region, moving minimum parcel size steps.
integer x;
for ( x = 0; x < 256; x += PLOT_STEP )
{
integer y;
for ( y = 0; y < 256; y += PLOT_STEP )
{
// Check the parcel at the given spot.
sReport += CheckParcelAt( x, y );
}
}
// Ensure the progress hove text is removed.
llSetText( "", < 1.0, 1.0, 1.0 >, 1.0 );
// Return the report.
return sReport;
}
//////////////////////////////////////////////////////////////////////
// Report on all parcels.
ReportOnAllParcels( integer bForceIM )
{
string sReport = CheckParcels();
if ( ( EMAIL_REPORT_TO == "" ) || bForceIM )
{
llInstantMessage( llGetOwner(), "\n" + sReport );
}
else
{
llEmail( EMAIL_REPORT_TO, "Parcel Settings Report (" + llGetTimestamp() + ")", sReport );
}
}
//////////////////////////////////////////////////////////////////////
// Default state.
default
{
//////////////////////////////////////////////////////////////////
// State entry.
state_entry()
{
// Do a run right now.
ReportOnAllParcels( FALSE );
// Set a timer.
llSetTimerEvent( 21600.0 );
}
//////////////////////////////////////////////////////////////////
// Respond to a touch.
touch_start( integer _ )
{
// If it's the owner...
if ( llDetectedKey( 0 ) == llGetOwner() )
{
ReportOnAllParcels( TRUE );
}
}
//////////////////////////////////////////////////////////////////
// Handle a timer event.
timer()
{
ReportOnAllParcels( FALSE );
}
}
Of course, what you should do is change the value of EMAIL_REPORT_TO so that it points to an email address you want the report sent to (or leave it empty if you'd prefer it to be sent via IM). If you want to check other settings on a plot you can modify the code of ReportOnParcelAt. As it's written it does a check every six hours. If you want to change that just modify the value passed to llSetTimerEvent.

Hope it's helpful to someone else.

No comments:

Post a Comment