User:Lum Pfohl/LSL Goodies/HI-WA Occupancy Counter System/Collection Server 1.05

From Second Life Wiki
Jump to navigation Jump to search

<lsl>

//  _                      ______  __      _     _
// | |                     | ___ \/ _|    | |   | |
// | |    _   _ _ __ ___   | |_/ / |_ ___ | |__ | |
// | |   | | | | '_ ` _ \  |  __/|  _/ _ \| '_ \| |
// | |___| |_| | | | | | | | |   | || (_) | | | | |
// \_____/\__,_|_| |_| |_| \_|   |_| \___/|_| |_|_|


//
// Lum's Collection Server Script
//
// Written by Lum Pfohl June 17, 2008
//
//

// Version
string __versionID = "01.50";

// Beware of llOwnerSay spam if you turn debug on...
integer __debug=FALSE;

// interval at which we would check emails when there are none
float checkInterval = 2.5;
float checkFastInterval = 0.25;
integer checkCountdown = 0;


// OI Population
list population;

// HI Population
list hiPopulation;

// Infohub / Welcome Area Population
list waPopulation;
list waAreas = ["Ahern", "Ambat", "Anzere", "Bear", "Braunworth", "Calleta", "Clementina", "Hanja", "Hyles", "Iris", "Isabel", "Mahulu", "Mauve", "Miramare", "OIP", "Periwinkle", "Ross", "Violet", "Warmouth", "Waterhead", "Wengen", "Korea"];
integer numEmailScripts = 16;
integer curEmailScript = 0;


// replacement routine for llEmail(), designed to intercept
// the email request and dispatch it to one of several slave email scripts
sendMessage(string toAddress, string subject, string messageBody) {

  // marshall the email parameters to pass to the slave email scripts
  string messageToSend = toAddress + "|" + subject + "|" + messageBody;

  if (__debug)
    llOwnerSay("linking: " + (string)curEmailScript + messageToSend);

  // contact the slave script (by number - curEmailScript) and pass the marshalled message
  llMessageLinked(LINK_THIS, curEmailScript, messageToSend, NULL_KEY);

  // increment currentEmail script pointer, resetting to zero as needed
  curEmailScript = (curEmailScript + 1) % numEmailScripts;

}



default
{

  //------------------------------------------------------------------------------------
  // On startup the server states it's key.  This key is required for resident counters
  // to send notification emails.
  //------------------------------------------------------------------------------------
  state_entry() {
    llOwnerSay("Server Key is " + (string)llGetKey());
    llSetTimerEvent(checkInterval); // Poll for emails.
    llOwnerSay("Email check interval set to " + (string)checkInterval + " seconds.");

    // Create a 100 element list of populations, corresponding to OI 1 thru 99
    // We recognize that there are not 100 OI's, and there is an anomalous "OI 22b"
    // which we will progammatically overcome.
    //
    // A value of "0" would indivate "uninitialized" and any other value
    // such as "0.0" would mean "zero residents, zero mentors"
    population = ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    population = population + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];

    // We setup 20 HI slots (HI - HI 16, HIP, HIP2, stored in that order).
    hiPopulation = ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];

    // We setup slots for HI 210 - 260
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    hiPopulation = hiPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];

    // We setup slots for 30 Infohubs and Welcome areas
    waPopulation = ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    waPopulation = waPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];
    waPopulation = waPopulation + ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0"];


  }

  //------------------------------------------------------------------------------------
  // Every time the timer expires, check for emails
  //------------------------------------------------------------------------------------
  timer() {
    llGetNextEmail("", ""); // Check for email with any sender address and subject.
    if (checkCountdown != 0) {
      if (checkCountdown-- == 1) {
        llSetTimerEvent(checkInterval);
      }
    }
  }

  //------------------------------------------------------------------------------------
  // If we get an email, check for notifications, and update the population list
  //------------------------------------------------------------------------------------
  email(string time, string address, string subj, string message, integer num_left) {

    // Remove the header
    message = llDeleteSubString(message, 0, llSubStringIndex(message, "\n\n") + 1);

    // Break of the message
    list notificationMessage = llParseString2List(message,["~",","],[]);
    string method = llList2String(notificationMessage, 0);

    if (method == "NOTIFY") {

      // Decompose the notification message string.
      string regionName = llList2String(notificationMessage, 1);
      integer residents = llList2Integer(notificationMessage, 2);
      integer mentors = llList2Integer(notificationMessage, 3);

      if (__debug) {
        llOwnerSay(regionName + ": " + (string)residents + " residents, " + (string)mentors + " mentors.");
      }

      if (llGetSubString(regionName, 0, 1) == "OI") {

        // Handle the case of the anomalous OI 22b - treat it as OI 19 (for storage purposes)
        // since there is no OI 19.
        integer oiNumber = 0;
        if (regionName == "OI 22b") {
          oiNumber = 19;
        } else if (regionName == "OIP") {
          // OI2 is a nonexistent OI, so we'll use that as OIP
          oiNumber = 2;
          waPopulation = llListReplaceList(waPopulation,  [(string)residents + "~" + (string)mentors], 14, 14);
        } else {
          oiNumber = (integer)llGetSubString(regionName, 2, -1);
        }

        // Replace the value at the appropriate OI number with the value
        // reported by the in-field ResCtr object.  The format stored will be
        // "<numResidents> ~ <numMentors>"  E.g.:  "2~1" indicates two residents,
        // and one mentor.
        population = llListReplaceList(population,  [(string)residents + "~" + (string)mentors], oiNumber-1, oiNumber-1);
      } else if (llGetSubString(regionName, 0, 1) == "HI") {

        // Handle the special cases of HI, HIP and HIP2, treating them as
        // HI 1, HI 17 and HI 18 respectively
        integer hiNumber = 0;
        if (regionName == "HI") {
          hiNumber = 1;
        } else if (regionName == "HIP") {
          hiNumber = 17;
        } else if (regionName == "HIP2") {
          hiNumber = 18;
        } else {
          hiNumber = (integer)llGetSubString(regionName, 2, -1);
        }

        // Make adjustments for the new HI 201 - HI 210 - We will store them
        // in slots 21 - 30
        if (hiNumber >= 201 && hiNumber <= 260) {
          hiNumber = hiNumber - 180;
        }

        // Replace the value at the appropriate HI number with the value
        // reported by the in-field ResCtr object.  The format stored will be
        // "<numResidents> ~ <numMentors>"  E.g.:  "2~1" indicates two residents,
        // and one mentor.

        if (hiNumber < 80) {
          hiPopulation = llListReplaceList(hiPopulation,  [(string)residents + "~" + (string)mentors], hiNumber-1, hiNumber-1);
        } else {
          llOwnerSay("Received an unknown HI " + (string)hiNumber);
        }
      }

    } else if (method == "NOTIFY WA") {

      // Decompose the notification message string.
      string regionName = llList2String(notificationMessage, 1);
      integer residents = llList2Integer(notificationMessage, 2);
      integer mentors = llList2Integer(notificationMessage, 3);

      if (__debug) {
        llOwnerSay(regionName + ": " + (string)residents + " residents, " + (string)mentors + " mentors.");
      }
      integer count = 0;
      ;
      for (count = 0; count < llGetListLength(waAreas); count++) {
        if (llList2String(waAreas, count) == regionName) {
          waPopulation = llListReplaceList(waPopulation,  [(string)residents + "~" + (string)mentors], count, count);
          count = 30;
        }
      }


    } else if (method == "QUERY") {

      // Decompose the return address (HUD UUID) from the message
      string returnAddress = llList2String(notificationMessage, 1);

      if (__debug) {
        llOwnerSay("QUERY (OI only) returnAddress = " + returnAddress);
      }
      // Send that object, the current OI population
      sendMessage(returnAddress + "@lsl.secondlife.com", "Query Response", llList2CSV(population));
    } else if (method == "QUERY HI") {

      // Decompose the return address (HUD UUID) from the message
      string returnAddress = llList2String(notificationMessage, 1);

      if (__debug) {
        llOwnerSay("QUERY (HI only) returnAddress = " + returnAddress);
      }
      // Send that object, the current OI population
      sendMessage(returnAddress + "@lsl.secondlife.com", "Query Response", llList2CSV(llDeleteSubList(hiPopulation, 30, 79)));
    } else if (method == "QUERY HI EXT") {

      // Decompose the return address (HUD UUID) from the message
      string returnAddress = llList2String(notificationMessage, 1);

      if (__debug) {
        llOwnerSay("QUERY (HI EXI) returnAddress = " + returnAddress);
      }
      // Send that object, the current OI population
      sendMessage(returnAddress + "@lsl.secondlife.com", "Query Response", llList2CSV(hiPopulation));
    } else if (method == "QUERY ALL") {

      // Decompose the return address (HUD UUID) from the message
      string returnAddress = llList2String(notificationMessage, 1);

      if (__debug) {
        llOwnerSay("QUERY (ALL) returnAddress = " + returnAddress);
      }
      // Send that object, the current OI population
      // llOwnerSay((string)llGetListLength(population) + "   " + (string)llGetListLength(hiPopulation));
      sendMessage(returnAddress + "@lsl.secondlife.com", "Query Response", llList2CSV(population) + "," + llList2CSV(llDeleteSubList(hiPopulation, 30, llGetListLength(hiPopulation)-1)));
    } else if (method == "QUERY ALL EXT") {

      // Decompose the return address (HUD UUID) from the message
      string returnAddress = llList2String(notificationMessage, 1);

      if (__debug) {
        llOwnerSay("QUERY (ALL EXT) returnAddress = " + returnAddress);
      }
      // Send that object, the current OI population
      // llOwnerSay((string)llGetListLength(population) + "   " + (string)llGetListLength(hiPopulation));
      sendMessage(returnAddress + "@lsl.secondlife.com", "Query Response", llList2CSV(population) + "!" + llList2CSV(hiPopulation) + "!" + llList2CSV(waPopulation));
    }

    // If we have received an email, switch to fast polling to see if there are other mail
    // trickling in.  Once a period of 10 checks goes by we can swtich batch to normal polling
    if (checkCountdown < 1) {
      llSetTimerEvent(checkFastInterval);
    }
    checkCountdown = 10;


  }

  touch_start(integer num) {

    llWhisper(0,llList2CSV(population));
    llWhisper(0," ");
    llWhisper(0,llList2CSV(hiPopulation));
    llWhisper(0," ");
    llWhisper(0,llList2CSV(waPopulation));     
    
    if (__debug) {
      __debug = FALSE;
      llOwnerSay("Debug is off.");
    } else {
      __deubg = TRUE;
      llOwnerSay("Debug is on.");
    }
  }
}

</lsl>