////////////////////////////////////////////////////////////////////// // Simple RLV-based group auto-changer. // By Antony Fairport. // Inspired by a question by Sally Lithanos in Builder's Brewery. // // Usage. // ====== // // This script needs RLV active in your viewer to work. You don't need // a relay, but you do need RLV turned on. RLV support must me 2.5 or // higher (so pretty much any modern viewer that has RLV or RLVa). // // Drop this script in a prim that you'll wear -- either make yourself // a HUD or attach the prim to your avatar (perhaps even drop it // inside somethign you wear). Then make a notecard and call it // "Group Rules" and drop it in the object along with the string. // // Add lines to the notecard like this: // // <region>=<group> // // Where <region> is a full region name and <group> is the group // you want to auto-change to when you enter that region. // // There is also a special region called "*". Use this to set the // default group to use. This group will be used when you enter // a region you've not listed elsewhere in the notecard. If you // don't use this your group will be set to none. An example // might be: // // Shackles=Friends of Z&A // Builders Resource=Builder's Brewery // Fermi=Little Blue Island // Little Blue Island=Little Blue Island // *=Raven Park // // // Revision history. // ================= // // 2013-05-27 // Initial version. ////////////////////////////////////////////////////////////////////// // Constants. string CONFIG_FILE = "Group Rules"; ////////////////////////////////////////////////////////////////////// // Global configuration. list g_lRegions; list g_lGroups; string g_sDefaultGroup; ////////////////////////////////////////////////////////////////////// // Config reading globals. key g_kConfig; integer g_iConfig; ////////////////////////////////////////////////////////////////////// // Refresh the owner's group. RefreshGroup() { integer iRegion; string sGroup; // If the region is in the region list... if ( ( iRegion = llListFindList( g_lRegions, [ llToLower( llGetRegionName() ) ] ) ) != -1 ) { // ...pull out the group for that region. sGroup = llList2String( g_lGroups, iRegion ); } else { // Otherwise, do we have a default? if ( g_sDefaultGroup ) { // Yes. Use that. sGroup = g_sDefaultGroup; } else { // No default, so assume we'll go to "none". sGroup = "none"; } } // Finally, force the group change. llOwnerSay( "Changing your group to '" + sGroup + "'" ); llOwnerSay( "@setgroup:" + sGroup + "=force" ); } ////////////////////////////////////////////////////////////////////// // Default state. default { ////////////////////////////////////////////////////////////////// // State entry. state_entry() { // Read the configuration. state Configure; } } ////////////////////////////////////////////////////////////////////// // Configuration state. state Configure { ////////////////////////////////////////////////////////////////// // State entry. state_entry() { // Let the user know what's happening. llOwnerSay( "Reading configutation..." ); // Clear out the config. g_lRegions = []; g_lGroups = []; g_sDefaultGroup = ""; // If it looks like we've got config... if ( llGetInventoryType( CONFIG_FILE ) == INVENTORY_NOTECARD ) { // ...start reading it. g_kConfig = llGetNotecardLine( CONFIG_FILE, g_iConfig = 0 ); } else { // Tell the user things aren't good. llOwnerSay( "No configuration found." ); } } ////////////////////////////////////////////////////////////////// // Handle data server responses. dataserver( key queryid, string data ) { // If this is our query... if ( queryid == g_kConfig ) { // If this isn't the end of the file... if ( data != EOF ) { // If the line doesn't look like it's a comment, and it isn't empty... if ( ( llGetSubString( data, 0, 0 ) != "#" ) && ( llStringTrim( data, STRING_TRIM ) != "" ) ) { // Split the line into a list. list sLineData = llParseString2List( data, [ "=" ], [] ); // Pull out the region name string sRegion = llToLower( llStringTrim( llList2String( sLineData, 0 ), STRING_TRIM ) ); // Pull out the group name. string sGroup = llStringTrim( llList2String( sLineData, 1 ), STRING_TRIM ); // If the region is the "wildcard" region... if ( sRegion == "*" ) { // ...then the group is the default group. g_sDefaultGroup = sGroup; // Mention that. llOwnerSay( "Default group: " + g_sDefaultGroup ); } else { // ...otherwise add to the list of regions and groups. g_lRegions += [ sRegion ]; g_lGroups += [ sGroup ]; // Mention what we've done. llOwnerSay( sRegion + " -> " + sGroup ); } } // Read the next line. g_kConfig = llGetNotecardLine( CONFIG_FILE, ++g_iConfig ); } else { // Config read. We're all set. state GroupChanger; } } } } ////////////////////////////////////////////////////////////////////// // Stage that handles group changing. state GroupChanger { ////////////////////////////////////////////////////////////////// // State entry. state_entry() { // Say that we're reading. llOwnerSay( "Group changer active." ); // Set the initial group. RefreshGroup(); } ////////////////////////////////////////////////////////////////// // Handle changes. changed( integer change ) { // Did the region change? if ( change & CHANGED_REGION ) { // It did. Refresh the group. RefreshGroup(); } // Did the inventory change? else if ( change & CHANGED_INVENTORY ) { // It did. Reload the config. llOwnerSay( "Rules change. Reloading..." ); llResetScript(); } } }