Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
15 kB
4
Indexable
// Visitors list 2.3
// by Paradox
//
// (English)
// Instruction
//
// You can add or remove admins by adding or removing an identifier (key) to the 'admins' variable.
// The 'scope' variable specifies scanning modes. AGENT_LIST_PARCEL - detects visitors on the same piece of land where the script is running; AGENT_LIST_PARCEL_OWNER - detects visitors to any lot in the region where the owner of the land is the same as the owner of the object in which the script is located; AGENT_LIST_REGION - Finds all visitors in the region.
// By simply clicking on an object, the administrator displays a list of visitors to the site.
// By long pressing on an object by the administrator, the list of visitors to the site is reset to zero.
// The 'Same group' status indicates whether the visitor had the same group active as the one assigned to the object in which the script is located.
// The 'Was out range' status indicates whether the visitor has left the land. If a visitor leaves the land, he is added to the list again the next time he visits.
//
// (Русский)
// Инструкция
//
// Добавлять или удалять админов можно, добавляя или удаляя идентификатор (ключ) в переменную 'admins'.
// Переменная 'scope' задаёт режимы сканирования. AGENT_LIST_PARCEL — обнаруживает посетителей на том же участке земли, где запущен скрипт; AGENT_LIST_PARCEL_OWNER — обнаруживает посетителей на любом участке в регионе, где владелец земли совпадает с владельцем объекта, в котором находится скрипт; AGENT_LIST_REGION — обнаруживает всех посетителей в регионе. 
// По простому нажатию на объект админом выводится список посетителей участка.
// По длительному нажатию на объект админом список посетителей участка обнуляется.
// Статус 'Same group' говорит о том, была ли у посетителя активна та же группа, что назначена объекту, в котором находится скрипт.
// Статус 'Was out range' говорит о том, покидал ли посетитель землю. Если посетитель покидал землю, то он вносится в список снова при следующем посещении.

//Global сonstants
list admins = ["7405e11e-67d8-4ac7-ad98-e9e90316e2e4"]; //Admins list. Admins: Paradox
integer scope = AGENT_LIST_PARCEL; //AGENT_LIST_PARCEL - returns only agents on the same parcel where the script is running; AGENT_LIST_PARCEL_OWNER - returns only agents on any parcel in the region where the parcel owner is the same as the owner of the parcel under the scripted object; AGENT_LIST_REGION - returns any/all agents in the region.
float timer_event_time = 1.0;
integer limit_reset_visitors_list  = 150;


//Global variables

list visitors_list;
integer resets_visitors_list_counter;
integer total_visitors;

//Functions

//Set functions for Click and Long click; 2.0; 2023.12.19; by Paradox
//
//For detailed instructions, see the example.

//Constants
float long_click_time = 3.0;

//Variables
integer touch_start_counter;
float touch_time_1;
float touch_time_2;


integer isClick()
{    
    if (touch_start_counter == 1)
    {
        touch_start_counter = 0;
        return TRUE;
    }
    else return FALSE;    
}

integer isLongClick()
{
    if (touch_start_counter == 1)
    {
        touch_time_2 = llGetTime();
    }
        
    if (touch_time_2 - touch_time_1 >= long_click_time)
    {
        touch_time_1 = touch_time_2;
        touch_start_counter = 0;
        return TRUE;    
    }
    else return FALSE;
}

integer isAdmin()
{
    return (llListFindList(admins, [(string) llDetectedKey(0)]) != -1);
}
integer isNameOnVisitorsList(list src, integer index)
{
    return (llListFindList(visitors_list, ["User name: " + llKey2Name(llList2Key(llList2List(src, index, index), 0))]) != -1);
}
string GetNameFromVisitorsList(integer index)
{
    return (llList2String(llParseString2List(llList2String(llList2List(visitors_list, index, index), 0), ["User name: "], []), 0));
}
integer ListFindListLastElement(list src, list test)
{
    integer srclen = llGetListLength(src);
    integer testlen = llGetListLength(test);
    
    integer idx = 0;
    integer cidx = 0;
    
    do
    {
        if ((idx = llListFindList(llList2List(src, cidx, -1), test)) != -1) 
        {
            cidx += idx + testlen;
        }
    }
    while (idx != -1 && cidx < srclen);    
    
    return cidx-testlen;
}
list isSameGroup(list scan_list, integer num_det)
{
    if (llSameGroup(llList2Key(llList2List(scan_list, num_det, num_det), 0)) == TRUE)
    {
        return ["Same group: Yes"];
    }
    else return ["Same group: No"];
}

// Convert Unix Time to SLT, identifying whether it is currently PST or PDT (i.e. Daylight Saving aware)
// Omei Qunhua December 2013
list weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

string Unix2PST_PDT(integer insecs)
{
    string str = Convert(insecs - (3600 * 8) );   // PST is 8 hours behind GMT
    if (llGetSubString(str, -3, -1) == "PDT")     // if the result indicates Daylight Saving Time ...
        str = Convert(insecs - (3600 * 7) );      // ... Recompute at 1 hour later
    return str;
}

// This leap year test is correct for all years from 1901 to 2099 and hence is quite adequate for Unix Time computations
integer LeapYear(integer year)
{
    return !(year & 3);
}

integer DaysPerMonth(integer year, integer month)
{
    if (month == 2)      return 28 + LeapYear(year);
    return 30 + ( (month + (month > 7) ) & 1);           // Odd months up to July, and even months after July, have 31 days
}

string Convert(integer insecs)
{
    integer w; integer month; integer daysinyear;
    integer mins = insecs / 60;
    integer secs = insecs % 60;
    integer hours = mins / 60;
    mins = mins % 60;
    integer days = hours / 24;
    hours = hours % 24;
    integer DayOfWeek = (days + 4) % 7;    // 0=Sun thru 6=Sat

    integer years = 1970 +  4 * (days / 1461);
    days = days % 1461;                  // number of days into a 4-year cycle

    @loop;
    daysinyear = 365 + LeapYear(years);
    if (days >= daysinyear)
    {
        days -= daysinyear;
        ++years;
        jump loop;
    }
    ++days;

    for (w = month = 0; days > w; )
    {
        days -= w;
        w = DaysPerMonth(years, ++month);
    }
    string str =  ((string) years + "-" + llGetSubString ("0" + (string) month, -2, -1) + "-" + llGetSubString ("0" + (string) days, -2, -1) + " " +
    llGetSubString ("0" + (string) hours, -2, -1) + ":" + llGetSubString ("0" + (string) mins, -2, -1) );

    integer LastSunday = days - DayOfWeek;
    string PST_PDT = " PST";                  // start by assuming Pacific Standard Time
    // Up to 2006, PDT is from the first Sunday in April to the last Sunday in October
    // After 2006, PDT is from the 2nd Sunday in March to the first Sunday in November
    if (years > 2006 && month == 3  && LastSunday >  7)     PST_PDT = " PDT";
    if (month > 3)                                          PST_PDT = " PDT";
    if (month > 10)                                         PST_PDT = " PST";
    if (years < 2007 && month == 10 && LastSunday > 24)     PST_PDT = " PST";
    return (llList2String(weekdays, DayOfWeek) + " " + str + PST_PDT);
}

// Function for sending messages to a public channel with a limit on sending speed (<200/10sec). 2023.12.14; by Paradox
integer MessagesCounter;
float MessagesTimerTime1;
float MessagesTimerTime2;
SaySpeedLimit(integer channel, string  message)
{
        //1 message start time
        if (MessagesCounter == 0)
        {
            MessagesTimerTime1 = llGetTime();
            MessagesCounter = 1;
        }
        
        // Saying
        llSay(channel, message);
        
        //2 message end time
        if (MessagesCounter == 1)
        {
            MessagesTimerTime2 = llGetTime();
            MessagesCounter = 0;
        }
        
        //Pause
        if (MessagesTimerTime2 - MessagesTimerTime1 <= 0.1)
        {
            llSleep(0.1); 
        }    
}

DisplayVisitersList()
{
    SaySpeedLimit(0, "\nСписок посетителей\n" + Unix2PST_PDT(llGetUnixTime()) +"\n\______________________________");
    integer i;
    integer lenVL = llGetListLength(visitors_list);
    for (i = 0; i < lenVL - 5; i += 6)
    {
        SaySpeedLimit(0, "\n\n" + llDumpList2String(llList2List(visitors_list, i, i + 5), "\n") + "\n");
    }
    total_visitors = resets_visitors_list_counter * limit_reset_visitors_list + llGetListLength(visitors_list) / 6;
    SaySpeedLimit(0, "\n______________________________\nВсего посетителей в списке: " + (string) (llGetListLength(visitors_list) / 6) + "\n\nЛимит автоматического обнуления\nсписка посетителей: " + (string) limit_reset_visitors_list + "\nКоличество автоматических обнулений\nсписка посетителей: " + (string) resets_visitors_list_counter + "\nВсего количество посетителей с учётом\nавтоматических обнулений списка: " + (string) total_visitors + "\n(" + (string) (llGetListLength(visitors_list) / 6) + " + " + (string) limit_reset_visitors_list + " * " + (string) resets_visitors_list_counter + " = " + (string) total_visitors + ")");
}

ResetVisitorsList()
{
    //Automatic reset of the visitor list
    if (llGetListLength(visitors_list) / 6 == limit_reset_visitors_list)
    {
        list temp_list = ["1"] + llList2List(visitors_list, llGetListLength(visitors_list) - 5, -1);
        visitors_list = [];
        visitors_list = temp_list;
        resets_visitors_list_counter += 1;
        llSay(0, "Обнуление..."); //For test  
        llSleep(1.5);     
    }
}

default
{
    state_entry()
    {
        llSetTimerEvent(timer_event_time);
        //For testing
        
        integer q = 0;
        for (q = 0; q < 148; ++q)
        {
           visitors_list += ["999"] + ["Display name: ddddddddddddddddddddddddddddddd"] + ["User name: uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"] + ["Time: " + Unix2PST_PDT(llGetUnixTime())] + ["Same group: Yes"] + ["Was out range: YYY"]; 
        }
        llSay (0, "Done 1");
        
        //
    }
    
    touch_start(integer total_number)
    {
        //For clicks
        touch_start_counter += 1;     
        if (touch_start_counter == 1)
        {       
            touch_time_1 = llGetTime();
        }      
    }
    
    touch(integer num_detected)
    { 
        //Long click event
        if (isLongClick() == TRUE)
        {
            //Admin Long click
            if (isAdmin() == TRUE)
            {
                visitors_list = [];
                resets_visitors_list_counter = 0;
                SaySpeedLimit(0, "\nВыполнено ручное обнуление списка посетителей;\nВыполнено обнуление счётчика автоматических\nобнулений списка посетителей");            
                DisplayVisitersList();
                SaySpeedLimit(0, "\nЧерез несколько секунд сканирование начнётся снова...");
                llSleep(1.5);       
            }    
        }     
    }
    
    touch_end(integer num_detected)
    {
        //Click event
        if (isClick() == TRUE)
        {
            //Admin Сlick
            if (isAdmin() == TRUE)
            {
                DisplayVisitersList();
            }    
        }  
    }    
    
    timer()
    {               
        //Adding to visitors_list
        list scan = llGetAgentList(scope, []);
        
        //For testing
        
        integer q = 0;
        for (q = 0; q < 100; ++q)
        {
           scan += ["uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"]; 
        }
        llSay (0, "Done 2");
        
        //
        
        integer i;
        integer len_scan = llGetListLength(scan);
        for(i = 0; i < len_scan; ++i)
        {
            if (llGetAgentSize(llList2Key(llList2List(scan, i, i), 0)) != ZERO_VECTOR
                    && 
                    (
                        isNameOnVisitorsList(scan, i) == FALSE
                        ||
                        (
                            isNameOnVisitorsList(scan, i) == TRUE 
                            &&
                            llList2String(visitors_list, ListFindListLastElement(visitors_list, ["User name: " + llKey2Name(llList2Key(llList2List(scan, i, i), 0))]) + 3) == "Was out range: Yes"
                        )
                    )
                )
            {            
                visitors_list += [(string) (llGetListLength(visitors_list) / 6 + 1)] + ["Display name: " + llGetDisplayName(llList2Key(llList2List(scan, i, i), 0))] + ["User name: " + llKey2Name(llList2Key(llList2List(scan, i, i), 0))] + ["Time: " + Unix2PST_PDT(llGetUnixTime())] + isSameGroup(scan, i) + ["Was out range: No"];

                llSay(0, "Test memory: " + (string) llGetUsedMemory()); //For testing
                
                ResetVisitorsList();
            } 
        }
        
        //Was out range status control
        i = 2;
        integer lenVL = llGetListLength(visitors_list);
        for (i = 2; i < lenVL - 3; i += 6)
        {
            if (llList2String(visitors_list, i + 3) == "Was out range: No" && llListFindList(scan, [llName2Key(GetNameFromVisitorsList(i))]) == -1)
            {
                llSay(0, "4: " + (string) llGetUsedMemory()); //For testing         
                visitors_list = llListInsertList(visitors_list, ["Was out range: Yes"], i + 3);
                visitors_list = llDeleteSubList(visitors_list, i + 4, i + 4);
            }     
        }
    }    
}
Leave a Comment