Don't click here unless you want to be banned.

LSL Wiki : ExampleSLMail

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
SL Mail module. Lets you receive, reply and send mail from within second life.

// SL Mail.lsl
// (c) 2007 Logic Scripted Products and Script Services
// Flennan Roffo

// VERSION
// Version: 1.1

// HISTORY
// Date         Version        Author               Comment
// --------------------------------------------------------------------------------------
// 28 aug 2007  V 1.0      Flennan Roffo       Created
//
//  1 sep 2007  V 1.1       Flennan Roffo      @Reply empties the recording buffer.
//                                                         @Send while recording ends recording
//                                                          and sends the mail if a mail address
//                                                          and subject are supplied.
//                                                          Fixed incorrect date in Unix2DateTime.

// LICENCE
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
// (Also available at http://www.gnu.org/copyleft/gpl.html) 

// DESCRIPTION
// Let's you record a message and sent to email and get messages and reply to messages.
// Must supply a valid mail adress and non-empty subject using chat commands.

// TODO:
// 1) Check for the maximum length of an email message (including newline and header).
// 2) Add adress book facility
// 3) Read adress book from notecard


string MailAdress = "";
string MailSubject = "";

string COMMAND_RECORD     = "@RECORD";
string COMMAND_CONTINUE   = "@CONTINUE";
string COMMAND_STOP       = "@STOP";
string COMMAND_MAIL       = "@MAIL";
string COMMAND_SUBJECT    = "@SUBJECT";
string COMMAND_SEND       = "@SEND";
string COMMAND_SEE       = "@SEE";
string COMMAND_IGNORE   = "@IGNORE";
string COMMAND_READ     = "@READ";
string COMMAND_DELETE   = "@DELETE";
string COMMAND_CLEAR      = "@CLEAR";
string COMMAND_REPLY    = "@REPLY";
string COMMAND_NEXT     = "@NEXT";
string COMMAND_PREV     = "@PREV";
string COMMAND_FIRST    = "@FIRST";
string COMMAND_LAST     = "@LAST";
string COMMAND_LIST     = "@LIST";
string COMMAND_SELECT   = "@SELECT";
string COMMAND_HELP       = "@HELP";
string COMMAND_INFO     = "@INFO";
string COMMAND_RESET      = "@RESET";
string COMMAND_SHOW       = "@SHOW";

string LSL_DOMAIN = "lsl.secondlife.com";

integer Recording = FALSE;

list    ChatRecording=[];
integer NumLines=0;
integer Length=0;

list TimeList=[];
list AddressList=[];
list SubjectList=[];
list BodyList=[];
integer NumMessages=0;
integer CurrentMessage=-1;

///////////////////////////////////////// Unix Time conversion //////////////////

integer DAYS_PER_YEAR        = 365;            // Non leap year
integer SECONDS_PER_YEAR     = 31536000;      // Non leap year
integer SECONDS_PER_DAY      = 86400;
integer SECONDS_PER_HOUR     = 3600;
integer SECONDS_PER_MINUTE     = 60;

///////////////////////////////////////// LeapYear /////////////////////////////////
integer LeapYear(integer year)
{
    if (year % 4 == 0)
    {
        if (year % 100 == 0)
        {
            if (year % 400 == 0)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 1;
        }
    }
    else
    {
        return 0;
    }
}

///////////////////////////////////// DaysPerMonth //////////////////////////////////////////
                
integer DaysPerMonth(integer year,integer month)
{
    if (month < 8)
    {
        if (month % 2 == 0)
        {
            if (month == 2)
            {
                if (LeapYear(year))
                {
                    return 29;
                }
                else
                {
                    return 28;
                }
            }
            else
            {
                return 30;
            }
        }
        else
        {
            return 31;
        }
    }
    else
    {
        if (month % 2 == 0)
        {
            return 31;
        }
        else
        {
            return 30;
        }
    }
}

/////////////////////////////////// DaysPerYear /////////////////////////////////////////////

integer DaysPerYear(integer year)
{
    if (LeapYear(year))
        return DAYS_PER_YEAR + 1;
    else
        return DAYS_PER_YEAR;
}

/////////////////////////////////////// Unix2DataTime ///////////////////////////////////////

list Unix2DateTime(integer unixtime)
{
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;
    integer day = days_since_1_1_1970;
    integer year  = 1970;
    integer days_per_year = DaysPerYear(year);
    
    while (day > days_per_year)
    {
        day -= days_per_year;
        ++year;
        days_per_year = DaysPerYear(year);
    }

    integer month = 1;
    integer days_per_month = DaysPerMonth(year,month);
    
    while (day > days_per_month)
    {
        day -= days_per_month;
        
        if (++month > 12)
        {    
            ++year;
            month = 1;
        }
        
        days_per_month = DaysPerMonth(year,month);
    }

    // Add 1 day since days are 1 based, not 0
    
    if (++day > DaysPerMonth(year,month))
    {
        day = 1;
        
        if (++month > 12)
        {
            month = 1;
            ++year;
        }
    }
        
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;
    integer minute      = second / SECONDS_PER_MINUTE;
    second               = second % SECONDS_PER_MINUTE;
    
    return [ year, month, day, hour, minute, second ];
}

///////////////////////////////////////// IsValidKeyFormat //////////////////////

integer IsValidKeyFormat(string str)
{
    string keychars = "0123456789abcdef";

    if (llStringLength(str) != 36)
        return FALSE;
        
    if( (llGetSubString( str, 8, 8 )     != "-" ||
        llGetSubString( str, 13, 13 )     != "-" ||
        llGetSubString( str, 18, 18 )  != "-" ||
        llGetSubString( str, 23, 23 )  != "-" ) )
        return FALSE;

    integer i;
    
    for (i = 0; i < 8; ++i)
    {
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)
            return FALSE;
    }

    for (i = 9; i < 13; ++i)
    {
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)
            return FALSE;
    }

    for (i = 14; i < 18; ++i)
    {
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)
            return FALSE;
    }

    for (i = 19; i < 23; ++i)
    {
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)
            return FALSE;
    }

    for (i = 24; i < 36; ++i)
    {
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)
            return FALSE;
    }

    return TRUE;
}

////////////////////////////////////////////// ValidMailAdress /////////////////

integer ValidMailAdress(string arg)
{
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));
    
    if (adress == "")
        return FALSE;
        
    list parse = llParseStringKeepNulls(adress, [ "@" ], []);
    string account = llList2String(parse,0);
    string domain  = llList2String(parse,1);
    
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)
        return FALSE;
    
    if (domain == LSL_DOMAIN)
    {
        return     IsValidKeyFormat(account);
    }
    else
    {
        list parsedomain = llParseString2List(domain, [ "." ], []);
    
        if (llGetListLength(parsedomain) < 2)
            return FALSE;
        
        integer num = llGetListLength(parsedomain);
        integer i;
        
        for (i = 0; i < num; ++i)
        {
            if (llStringLength(llList2String(parsedomain,i)) < 2)
            {
                return FALSE;
            }
        }
    }
    
    return TRUE;
}

//////////////////////////////////// SendMail //////////////////////////////////////////

SendMail()
{
    llOwnerSay("Sending message to '" + MailAdress + "' with subject '" + MailSubject +"'.");
    llEmail(MailAdress, MailSubject, llDumpList2String(ChatRecording, "\n"));
}

//////////////////////////////////// Show //////////////////////////////////////////////

Show()
{
    integer i;
    
    llOwnerSay("Current chat recording is:");
    
    for (i = 0; i < NumLines; ++i)
    {
        llOwnerSay(llList2String(ChatRecording,i));
    }
    
    llOwnerSay("Lines is " + (string)NumLines);
    llOwnerSay("Message length is " + (string)Length);
}

//////////////////////////////////// Read //////////////////////////////////////////////

Read()
{
    llOwnerSay("Reading message " + (string)CurrentMessage + " from mail buffer.");
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);
    list datetime = Unix2DateTime(time);
    string Address = llList2String(AddressList,CurrentMessage);
    string Subject = llList2String(SubjectList,CurrentMessage);
    string Body    = llList2String(BodyList,CurrentMessage);
    llOwnerSay("Date   : " + (string)llList2Integer(datetime,0) + "-" + (string)llList2Integer(datetime,1) + "-" + (string)llList2Integer(datetime,2));
    llOwnerSay("Time   : " + (string)llList2Integer(datetime,3) + ":" + (string)llList2Integer(datetime,4) + ":" + (string)llList2Integer(datetime,5));
    llOwnerSay("Address: " + Address);
    llOwnerSay("Subject: " + Subject);
    llOwnerSay("Begin of message body:");
    llOwnerSay("-------------------------");
    llOwnerSay(Body);
    llOwnerSay("-------------------------");
    llOwnerSay("End of message body.");
}

////////////////////////////////////// List ////////////////////////////////////////////

List()
{
    integer i;
    
    llOwnerSay("The mail buffer contains the following messages:\n");
    
    for (i = 0; i < NumMessages; ++i)
    {
        list datetime=Unix2DateTime(llList2Integer(TimeList,i));
        llOwnerSay("Message: " + (string)i);
        llOwnerSay("Date   : " + (string)llList2Integer(datetime,0) + "-" + (string)llList2Integer(datetime,1) + "-" + (string)llList2Integer(datetime,2));
        llOwnerSay("Time   : " + (string)llList2Integer(datetime,3) + ":" + (string)llList2Integer(datetime,4) + ":" + (string)llList2Integer(datetime,5));
        llOwnerSay("From:    " + llList2String(AddressList,i));
        llOwnerSay("Subject: " + llList2String(SubjectList,i));
    }
}

////////////////////////////////////// Help ////////////////////////////////////////////

Help()
{
    llOwnerSay("HELP for SL Mail.");
    llOwnerSay("COMMANDS:");
    llOwnerSay("@HELP               - displays help info.");
    llOwnerSay("@INFO               - display mailaddress of this object.");
    llOwnerSay("@RECORD             - start recording.");
    llOwnerSay("@CONTINUE           - continue recording.");
    llOwnerSay("@STOP               - stop recording.");
    llOwnerSay("@IGNORE             - ignore the recording.");
    llOwnerSay("@SHOW               - show what your recorded.");
    llOwnerSay("@SEND               - send the recording.");
    llOwnerSay("@MAIL <mailadress>  - set the mail adress.");
    llOwnerSay("@SUBJECT subject    - set the mail subject.");
    llOwnerSay("@LIST               - list messages in mail buffer.");
    llOwnerSay("@SELECT <message>   - select message from mail buffer.");
    llOwnerSay("@READ               - read current message from mail buffer.");
    llOwnerSay("@NEXT               - read next message from mail buffer.");
    llOwnerSay("@PREV               - read previous message from mail buffer.");
    llOwnerSay("@FIRST              - read first message from mail buffer.");
    llOwnerSay("@LAST               - read last message from mail buffer.");
    llOwnerSay("@DELETE             - delete current message from mail buffer.");
    llOwnerSay("@CLEAR              - clear the mail buffer.");
    llOwnerSay("@REPLY              - reply to current message.");
    llOwnerSay("@RESET              - reset the script.");
}

////////////////////////////////////////// Info ////////////////////////////////////////////

Info()
{
    llOwnerSay("The mail address for this object is:");
    llOwnerSay((string)llGetKey() + "@" + LSL_DOMAIN);
}

///////////////////////////////////////////// default //////////////////////////////////////

default
{
    state_entry()
    {
        llListen(0, "", llGetOwner(), "");
        llOwnerSay("SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.");
        Info();
        llSetTimerEvent(0.2);
    }
    
    listen(integer channel, string name, key id, string message)
    {
        list   parse = llParseStringKeepNulls(message, [ " "], []);
        string command = llToUpper(llList2String(parse,0));
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);
        integer nargs = llGetListLength(parse);
            
        if (Recording)
        {
            if (command == COMMAND_STOP)
            {
                llOwnerSay("Recording stopped. Type @SHOW to see the message you have entered, or @SEND to send it.");
                Recording = FALSE;
            }
            else if (command == COMMAND_SEND)
            {
                Recording = FALSE;
                
                if (MailAdress == "")
                {
                    llOwnerSay("Must supply a mail adress. Type @MAIL <address> to enter a mail address.");
                }
                else if (MailSubject == "")
                {
                    llOwnerSay("Must supply a subject. Type @SUBJECT <subject> to enter a subject.");
                }
                else
                {
                    SendMail();
                }   
            }
            else
            {
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];
                ++NumLines;
                Length += llStringLength(message) + 2;
            }
        }
        else
        {
            if (command == COMMAND_RECORD)
            {
                llOwnerSay("Start recording your message. Type @STOP to end recording.");
                ChatRecording = [];
                NumLines=0;
                Length=0;
                Recording = TRUE;
            }
            else if (command == COMMAND_CONTINUE)
            {
                llOwnerSay("Continue recording your message. Type @STOP to end recording.");
                Recording = TRUE;
            }
            else if (command == COMMAND_REPLY)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    MailAdress = llList2String(AddressList,CurrentMessage);
                    MailSubject = "Re: " + llList2String(SubjectList,CurrentMessage);
                    ChatRecording = [];
                    NumLines=0;
                    Length=0;
                    Recording = TRUE;
                }
            }
            else if (command == COMMAND_MAIL)
            {
                if (nargs == 1)
                {
                    llOwnerSay("Mail address is: '" + MailAdress + "'.");
                }
                else if (ValidMailAdress(arg))
                {
                    MailAdress = arg;
                }
                else
                {
                    llOwnerSay("Mail adress format not valid.");
                }
            }
            else if (command == COMMAND_SUBJECT)
            {
                if (nargs == 1)
                {
                    llOwnerSay("Subject is: '" + MailSubject + "'.");
                }
                else
                {
                    MailSubject = arg;
                }
            }
            else if (command == COMMAND_STOP)
            {
                llOwnerSay("Not recording.");
            }
            else if (command == COMMAND_SEND)
            {
                if (NumLines == 0)
                {
                    llOwnerSay("No lines recorded.");
                }
                else if (MailAdress == "")
                {
                    llOwnerSay("No mail adress supplied. Type @MAIL <adress> to enter a mail adress.");
                }
                else if (MailSubject == "")
                {
                    llOwnerSay("No subject supplied Type @SUBJECT <subject> to enter a subject.");
                }
                else
                {
                    SendMail();
                }
            }
            else if (command == COMMAND_IGNORE)
            {
                if (NumLines == 0)
                {
                    llOwnerSay("No lines recorded.");
                }
                else
                {
                    ChatRecording = [];
                    NumLines = 0;
                    Length = 0;
                }
            }
            else if (command == COMMAND_SHOW)
            {
                if (NumLines == 0)
                {
                    llOwnerSay("No lines recorded.");
                }
                else
                {
                    Show();
                }
            }
            else if (command == COMMAND_READ)
            {
                if (NumMessages == 0)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    Read();
                }
            }
            else if (command == COMMAND_NEXT)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    if (CurrentMessage == NumMessages - 1)
                    {
                        llOwnerSay("Already at last message.");
                    }
                    else
                    {
                        ++CurrentMessage;
                        Read();
                    }
                }
            }
            else if (command == COMMAND_PREV)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    if (CurrentMessage == 0)
                    {
                        llOwnerSay("Already at first message.");
                    }
                    else
                    {
                        --CurrentMessage;
                        Read();
                    }
                }
            }
            else if (command == COMMAND_FIRST)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    if (CurrentMessage == 0)
                    {
                        llOwnerSay("Already at first message.");
                    }
                    else
                    {
                        CurrentMessage = 0;
                        Read();
                    }
                }
            }
            else if (command == COMMAND_LAST)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    if (CurrentMessage == NumMessages - 1)
                    {
                        llOwnerSay("Already at last message.");
                    }
                    else
                    {
                        CurrentMessage = NumMessages - 1;
                        Read();
                    }
                }
            }
            else if (command == COMMAND_LIST)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    List();
                }
            }
            else if (command == COMMAND_SELECT)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else if (nargs == 1)
                {
                    llOwnerSay("Need to supply a message number.");
                }
                else
                {
                    integer msgnum = (integer)arg;
                     
                    if (msgnum < 0 || msgnum >= NumMessages)
                    {
                        llOwnerSay("Message number " + arg + " not in mail buffer.");
                    }
                    else
                    {
                        CurrentMessage = msgnum;
                    }
                }
            }
            else if (command == COMMAND_DELETE)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);
                    --NumMessages;
                     
                    if (NumMessages == 0)
                    {
                        CurrentMessage = -1;
                    }
                    else if (CurrentMessage >= NumMessages)
                    {
                        CurrentMessage = NumMessages - 1;
                    }
                }
            }
            else if (command == COMMAND_CLEAR)
            {
                if (CurrentMessage == -1)
                {
                    llOwnerSay("The mail buffer is empty.");
                }
                else
                {
                    TimeList=[];
                    AddressList=[];
                    SubjectList=[];
                    BodyList=[];
                    NumMessages=0;
                    CurrentMessage=-1;
                }
            }
            else if (command == COMMAND_HELP)
            {
                Help();
            }
            else if (command == COMMAND_INFO)
            {
                Info();
            }
            else if (command == COMMAND_SHOW)
            {
                Show();
            }
            else if (command == COMMAND_RESET)
            {
                llResetScript();
            }
        }
    }
    
    timer()
    {
        llGetNextEmail("", "");
    }
    
    email(string time, string address, string subject, string body, integer queued)
    {
        llOwnerSay("You received a new message.");
        TimeList = (TimeList=[]) + TimeList + [time];
        AddressList = (AddressList=[]) + AddressList + [address];
        SubjectList = (SubjectList=[]) + SubjectList + [subject];
        BodyList = (BodyList=[]) + BodyList + [body];
        ++NumMessages;
        
        if (CurrentMessage == -1)
        {
            CurrentMessage = 0;
        }
        else
        {
            CurrentMessage = NumMessages - 1;
        }
    }
}
// End SL Mail.lsl



Examples
There is no comment on this page. [Display comments/form]