CODE
// ===============================================================
// Lindsey Dassin's Online Status Tracker for Multiple Avatars
// (c) 2005 Lindsey Dassin
// ===============================================================
//
// This work is licensed under the
// Creative Commons Attribution-NonCommercial-ShareAlike License.
// To view the full copy of this license, please visit
// http://creativecommons.org/licenses/by-nc-sa/2.0/
//
// ===============================================================
// How to use:
// Create a notecard called "Scribery Staff" (or whatever you change
// NOTECARD_NAME to be).
// In that notecard, list the agent keys you wish to track, one per line.
// Place the notecard into the object.
// Then add this script.
//
// To get an agent's key, create an object, create a new script inside it,
// and copy/paste/uncomment the following code snippet:
// ===============================================================
// default {
// touch_start( integer total_num ) {
// llOwnerSay( "The agent key for "
// + llDetectedName( 0 )
// + " is "
// + (string)llDetectedKey( 0 )
// );
// }
// }
// ===============================================================
//
// I made this script for Padraig Stygian, who takes care of me in both Second
// Life and First Life. I <3 you very much!
// The name of the notecard
string NOTECARD_NAME = "Scribery Staff";
// How often (in seconds) to update agent status
float UPDATE_PERIOD = 60.0;
// status text color/alpha
vector TEXT_COLOR = < 1.0, 1.0, 1.0 >;
float TEXT_ALPHA = 1.0;
list STATUS_TEXT = [ "OFFLINE", "ONLINE" ];
list MONTH_NAME = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
list dataServKey;
list agentKey;
list agentName;
list agentStatus;
list agentLastSeen;
integer staffCount;
integer count;
string currentDateTime;
// Taken directly from the wiki, and modified only for syntax errors.
string GetPSTDate()
{
string DateToday = "";
string DateUTC = llGetDate();
if (llGetGMTclock() < 28800) // that's 28800 seconds, a.k.a. 8 hours.
{
list DateList = llParseString2List(DateUTC, ["-", "-"], []);
integer year = llList2Integer(DateList, 0);
integer month = llList2Integer(DateList, 1);
integer day = llList2Integer(DateList, 2);
day = day - 1;
if (day == 0) // if day is the 1st of a month, fix the date
{
if (month == 1) // if it is January
{
year = year - 1; // wind back the year
month = 12; // set the month to December
day = 31; // set to last day of December
}
else
if (month == 3) // if it is March
{
month = month - 1; // wind back one month
if ( (year % 4) == 0 ) // if it is a leap year
{
day = 29; // in a leap year, Feburary has 29 days
}
else day = 28;
}
else
if (month == 5 || month == 7 || month == 10 || month == 12 ) // if it is a month following a month with 30 days
{
month = month - 1; // wind back one month
day = 30; // and set the day to 30
}
else
if (month == 2 || month == 4 || month == 6 || month == 8 || month == 9 || month == 11) // This IF is redundant but easier to read the code
{
month = month - 1; // wind back one month
day = 31; // and set the day to 31
}
}
DateToday = (string)year + "-" + (string)month + "-" + (string)day;
}
else
{
DateToday = llGetDate();
}
return (DateToday);
}
// Returns a string of the current date and time, PST
string getCurrentDateTime() {
integer minIntoDay;
string retVal;
list dateVal;
string minStr;
string hourStr;
// Get the date portion
dateVal = llParseString2List( GetPSTDate(), [ "-", "-" ], [ ] );
// Get the time portion
minIntoDay = llFloor( llGetWallclock() / 60.0 );
hourStr = (string)( minIntoDay / 60 );
minStr = (string)( minIntoDay % 60 );
if( minIntoDay % 60 < 10 ) {
minStr = "0" + minStr;
}
return llList2String( dateVal, 2 )
+ "-"
+ llList2String( MONTH_NAME, llList2Integer( dateVal, 1 ) - 1 )
+ "-"
+ llList2String( dateVal, 0 )
+ " "
+ hourStr
+ ":"
+ minStr
;
}
// Searches for the notecard, and requests the number of lines
default {
state_entry() {
llSetText( "Searching for notecard \"" + NOTECARD_NAME + "\"",
TEXT_COLOR, TEXT_ALPHA );
dataServKey = [ llGetNumberOfNotecardLines( NOTECARD_NAME ) ];
}
dataserver( key query_id, string data ) {
integer i;
if( query_id == llList2Key( dataServKey, 0 )) {
staffCount = (integer)data;
if( staffCount == 0 ) {
llSay( 0, NOTECARD_NAME + " has no data!" );
} else {
// Initialize all lists as full of empty values.
// That way llListReplaceList( ~ ) works.
agentKey = [ ];
agentName = [ ];
agentLastSeen = [ ];
for( i = 0; i < staffCount; i++ ) {
agentKey += [ "" ];
agentName += [ "" ];
agentLastSeen += [ "" ];
}
state get_keys;
}
}
}
}
// Retrieves the agent keys from the notecard.
state get_keys {
state_entry() {
integer i;
llSetText( "Getting agent keys...", TEXT_COLOR, TEXT_ALPHA );
count = 0;
dataServKey = [ ];
for( i = 0; i < staffCount; i++ ) {
dataServKey += [ llGetNotecardLine( NOTECARD_NAME, i ) ];
}
}
dataserver( key query_id, string data ) {
integer index;
index = llListFindList( dataServKey, [ query_id ] );
if( index != -1 ) {
agentKey = llListReplaceList( agentKey, [ (key)data ],
index, index );
// Go to the next state when all data requests have been received.
count++;
if( count == staffCount ) {
state get_names;
}
}
}
}
// Retrieves the agent names from the list of keys
state get_names {
state_entry() {
integer i;
llSetText( "Getting agent names...", TEXT_COLOR, TEXT_ALPHA );
dataServKey = [ ];
count = 0;
for( i = 0; i < staffCount; i++ ) {
dataServKey += [
llRequestAgentData( llList2Key( agentKey, i ), DATA_NAME )
];
}
}
dataserver( key query_id, string data ) {
integer index;
index = llListFindList( dataServKey, [ query_id ] );
if( index != -1 ) {
agentName = llListReplaceList( agentName, [ data ],
index, index );
// Go to the next state when all data requests have been received.
count++;
if( count == staffCount ) {
state get_status;
}
}
}
}
// Gets the online/offline status for each agent. If an agent is "online",
// the current date/time will be associated with the agent key.
state get_status {
state_entry() {
integer i;
llSetText( "Getting online status...", TEXT_COLOR, TEXT_ALPHA );
currentDateTime = getCurrentDateTime();
agentStatus = [ ];
for( i = 0; i < staffCount; i++ ) {
agentStatus += "";
}
dataServKey = [ ];
count = 0;
for( i = 0; i < staffCount; i++ ) {
dataServKey += [
llRequestAgentData( llList2Key( agentKey, i ), DATA_ONLINE )
];
}
}
dataserver( key query_id, string data ) {
integer index;
integer i;
index = llListFindList( dataServKey, [ query_id ] );
if( index != -1 ) {
i = (integer)data;
agentStatus = llListReplaceList( agentStatus, [ i ],
index, index );
// If online, replace the "last seen" time
if( i == 1 ) {
agentLastSeen = llListReplaceList( agentLastSeen,
[ currentDateTime ], index, index );
}
// Go to the next state when all data requests have been received.
count++;
if( count == staffCount ) {
state ready;
}
}
}
}
// The clickable "ready" state. Gives a report of agent status.
state ready {
state_entry() {
llSetText( "", TEXT_COLOR, TEXT_ALPHA );
// Refresh the online/offline status periodically
llSetTimerEvent( UPDATE_PERIOD );
}
timer() {
state get_status;
}
touch_start( integer total_num ) {
integer i;
integer status;
string str;
string lastSeen;
// We've been touched! Give a report!
for( i = 0; i < staffCount; i++ ) {
status = llList2Integer( agentStatus, i );
lastSeen = llList2String( agentLastSeen, i );
str = llList2String( agentName, i )
+ " "
+ llList2String( STATUS_TEXT, status );
// If the agent *was* online, report the last time seen
if(( status == 0 ) && ( lastSeen != "" )) {
str += ", last seen " + lastSeen;
}
llSay( 0, str );
}
}
}