// Simple visitor counter and lm giver script.
//
// Can also run as a simple 'add me to the waiting list' script
// too (i.e. remembers everyone who touches the object).
//
// Just finds the first landmark stored in the prim and
// gives it to non-owners on touch.
//
// For owners, if the prim is touched, presents a simple
// dialog to either list visitors or reset the visitors counts.
//
// Kimm Paulino
// Written for Vikki Hastings, Oct 2010
// Updated for waiting list, Mar 2012
// Configure the behaviour we want
integer gWaitingList = FALSE; // enable waiting list only functionality
integer gLogDates = TRUE; // Include timestamps in the log
integer gJustDates = FALSE; // But only dates (not timestamps)
integer gKeepFirst = FALSE; // Keep the first visit of someone, not the last
string gFloatingText = ""; // Set to "" to disable
vector gFloatingTextColour = <1.0, 1.0, 1.0>;
float gFloatingTextAlpha = 1.0;
float gSensorRange = 15.0;
integer MAX_VISITORS = 30;
list gVisitors;
list gVisitorTimes;
integer gVisitorCount;
integer gChannel;
integer gListenHandle;
integer getRandomChannel()
{
// Some magic I got of the SL wiki somewhere ...
return -llRound(llFrand( llFabs(llSin(llGetGMTclock())) * 1000000 )) - 11;
}
listVisitors ()
{
llOwnerSay("----------------");
llOwnerSay("Total number of visits: " + (string)gVisitorCount);
if (gVisitorCount > 0)
{
llOwnerSay("Most recent visitors:");
integer i;
integer len = llGetListLength(gVisitors);
for (i=0; i < len; i++)
{
if (gLogDates)
{
llOwnerSay("[" + llList2String (gVisitorTimes, i) + "] " +llList2String(gVisitors,i));
}
else
{
llOwnerSay(llList2String(gVisitors,i));
}
}
}
}
resetVisitors()
{
llOwnerSay ("Resetting visitor count");
gVisitors = [];
gVisitorTimes = [];
gVisitorCount = 0;
}
addVisitor(string name)
{
// see if we've already seen this one
integer idx = llListFindList(gVisitors, (list)name);
if (idx != -1 )
{
// Already in the list, so:
// If storing dates, then need to decide if we are keeping
// the first visit or the last
//
// If we are not keeping dates, just don't bother logging again
if (!gLogDates)
{
return;
}
if (gKeepFirst)
{
// Already have the entry we wish to keep ...
return;
}
// ok, we are keeping the last visits, so remove
// the name from the list and let the rest of the function
// add it in again!
gVisitors = llDeleteSubList (gVisitors, idx, idx);
gVisitorTimes = llDeleteSubList (gVisitorTimes, idx, idx);
}
else
{
// Note: Will count people who visited before but have
// now dropped off the end of the 'last visitors' list, but
// thats all.
gVisitorCount ++;
}
//llOwnerSay ("Adding " + name);
gVisitors += name;
if (gJustDates)
{
gVisitorTimes += llGetDate();
}
else
{
list timestamp = llParseString2List(llGetTimestamp(),["T","."],[""]);
string time = llList2String(timestamp, 0) + " " + llList2String(timestamp, 1);
gVisitorTimes += time;
}
// See if we are at the end of the list
// this helps to keep memory limits down
// and also creates a rolling list of most
// recently seen avs
if (llGetListLength(gVisitors) > MAX_VISITORS)
{
// Remove first entry in the list
gVisitors = llDeleteSubList (gVisitors, 0, 0);
gVisitorTimes = llDeleteSubList (gVisitorTimes, 0, 0);
}
}
default
{
on_rez (integer start_param)
{
llResetScript();
}
state_entry()
{
resetVisitors();
gChannel = getRandomChannel();
llSetText (gFloatingText, gFloatingTextColour, gFloatingTextAlpha);
if (!gWaitingList)
{
// Range, angle, rate
// So 5m range, 180 deg, every 5 secs
llSensorRepeat ("", NULL_KEY, AGENT, gSensorRange, PI, 5.0);
}
}
sensor(integer total_number)
{
integer i;
//llSay (0, "Found " + (string)total_number);
for (i=0 ; i
Visitor Counter and Landmark Giver
Written by: Headmaster