Code: Time Tracker Plugin

time_tracker_plugin.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
//                   CONFIGURATION                      //
//////////////////////////////////////////////////////////
// API key - can be anything, used as a password.
string API_KEY = "A1364788-B702-4413-B937-7A57E32B43CE";
string EMAIL = "scoobydoo@gmail.com";
///////////////////////////////////////////////////////////////////////////
//                              INTERNALS                                //
///////////////////////////////////////////////////////////////////////////
 
list actives = [];
list agents = [];
list times = [];
integer emailSent = 0;
 
default
{
    state_entry() {
        // ☀ Time Tracker (h:m:s) ☀\n
        // Morgan LeFay - 3
        string text = llList2String(llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXT]), 0);
        list split = llParseString2List(text, ["☀ Time Tracker (h:m:s) ☀"], [""]);
        list textTimes = llParseString2List(llList2String(split, 0), ["\n"], [""]);
        if(llGetListLength(textTimes) == 0) jump no_text;
        list displayLine = [];
        do {
            list line = llParseString2List(llList2String(textTimes, 0), [" - "], [""]);
            if(llGetListLength(line) != 2) jump continue;
            agents += llList2String(line, 0);
            // h:m:s
            list time = llParseString2List(llList2String(line, 1), [":"], [""]);
            times += llList2Integer(time, 2) + llList2Integer(time, 1) * 60 + llList2Integer(time, 0) * 3600;
            displayLine += agents + " - " + (string)times;
@continue;
        } while(textTimes = llDeleteSubList(textTimes, 0, 0));
        llSetText("☀ Time Tracker (h:m:s) ☀" + "\n" + llDumpList2String(displayLine, "\n"), <1,1,0>, 1);
@no_text;
        integer comChannel = ((integer)("0x"+llGetSubString(API_KEY,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        llListen(comChannel, "[K] Agent Registry", "", "");
        llSetTimerEvent(1);
    }
    listen(integer channel, string name, key id, string message) {
        // B522E348-9F1C-46AF-9D4A-59BFA9668E16#Morgan LeFay|93F8F728-FE99-441A-9BF0-203D835CA3E6#Some Agent
        // set all agents as not active.
        integer itra = llGetListLength(agents)-1;
        do {
            actives = llListReplaceList(actives, (list)0, itra, itra);
        } while(--itra>=0);
        // now we got a fresh set of active agents
        list data = llParseString2List(message, ["|"], [""]);
        do {
            list line = llParseString2List(llList2String(data, 0), ["#"], [""]);
            if(llGetListLength(line) != 2) jump continue;
            string name = llList2String(line, 1);
            integer idx = llListFindList(agents, (list)name);
            // if they're already in the list, set to active and continue;
            if(~idx) {
                actives = llListReplaceList(actives, (list)1, idx, idx);
                jump continue;
            }
            actives += 1; 
            agents += name;
            times += 0;
@continue;
        } while(data = llDeleteSubList(data, 0, 0));
    }
    timer() {
        if(llGetListLength(agents) == 0) return;
        // Add a second to registered agents.
        integer itra = llGetListLength(agents)-1;
        list displayLine = [];
        do {
            integer time = llList2Integer(times, itra);
            // if they're not active, don't increment the timer, but...
            if(llList2Integer(actives, itra) == 0) jump continue;
            times = llListReplaceList(times, (list)(time+1), itra, itra);
            integer agentHours = time/3600;
            integer agentMinutes = (time % 3600) / 60;
            integer agentSeconds = (time % 3600) % 60;
            displayLine += llList2String(agents, itra) + " - " + (string)agentHours + ":" + (string)agentMinutes + ":" + (string)agentSeconds;
@continue;
            // ...display them.
        } while(--itra>=0);
        list dateComponents = llParseString2List(llGetDate(), ["-"], []);
        integer year  = (integer) llList2String(dateComponents, 0);
        integer month = (integer) llList2String(dateComponents, 1);
        integer day   = (integer) llList2String(dateComponents, 2);
        string dayOfWeek = llList2String ( ["Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"],
                       (year + (year >> 2) - ((month < 3) & !(year & 3)) + day
                       + (integer)llGetSubString( "_033614625035", month, month )) % 7 );
        if(dayOfWeek == "Friday" && llGetObjectDesc() == "email=notsent") {
            llEmail(EMAIL, "NEW FOUND LAND EMPLOYEE REPORT", llDumpList2String(displayLine, "\n"));
            llSetObjectDesc("email=sent");
            llSetText("", <1,1,0>, 1);
            llResetScript();
        }
        if(dayOfWeek == "Friday") jump noemail;
        llSetObjectDesc("email=notsent");
@noemail;
        // Set text.
        llSetText("☀ Time Tracker (h:m:s) ☀" + "\n" + llDumpList2String(displayLine, "\n"), <1,1,0>, 1);
    }
    changed(integer change) {
        if (change & (CHANGED_REGION | CHANGED_REGION_START))
            llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}