SLU Donation / Reminder Script - SLUniverse Forums
Navigation » SLUniverse Forums > Development Discussion and Support > Scripting > Script Library » SLU Donation / Reminder Script


Script Library Post useful scripts here.

 
Reply
 
LinkBack Thread Tools Display Modes
Old 05-28-2012, 10:27 PM   #1 (permalink)
Senior Member

*SLU Supporter*
 
Samantha Poindexter's Avatar
 
Join Date: Jun 2009
Posts: 1,012
SL Join Date: February 13, 2006
Business: Samantha's Shirts
Client: Cool VL Viewer 1.26.8

Awards: 1
Best Drama Summary 
SLU Donation / Reminder Script

I'm going to start with a bunch of disclaimers that may end up being longer than the script itself.

This may not be of any use to anybody else, but it was something I wanted, and I thought I might perhaps not be alone.

I wanted an object that would do the following things:
  1. Accept L$ donations to SLU and pass them along to Cris
  2. Remind me after 30 days had gone by that it was probably time to do it again.
(Item #1 would save me the five valuable seconds it would take me to find "Cristiano Midnight" in Search. On the other hand, while item #2 could just as easily been designed to automatically debit my account every 30 days, I don't keep a lot of cash on my avatar, and an unexpected payment could be problematic. This compromise fits my particular needs.)

I am not really a scripter, so I followed my usual approach of taking an existing script that was somewhere in the right ballpark (in this case, my SLU shirt vendor), stripping out everything that didn't do what I wanted here (about 95% of it), and then filling in whatever else was needed. There are probably bits that could be more efficient.

It occurred to me while testing this that I ought to allow people other than the object's owner to donate to SLU as well, without affecting the reminders sent to the owner. And that the owner should be able to check when their own last payment was made. In other words, some slight feature bloat happened.

Finally, note that this script requires you to grant permission to take L$ from your account and give it to somebody else, because, you know, that's what it's for. Caveat avatar, check the code, and all that.

Code:
// Support SLU!
string last = "never. For shame!";
integer lastamount = 0;
key recipient = "0d2d7814-8b2d-4db1-81b8-96b507104e89"; // Cris

default
{
    state_entry()
    {
        //get permission to give Cris the L$
        llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
        } 


    touch_start(integer total_number)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            llOwnerSay("Your last donation, of L$" + (string)lastamount + ", was " + last);
        }
        else
        {
            llSay(0, "Pay this object to support SLU!");
        }
    
    } 
    
    money(key id, integer amount)
    {
        if ( id != llGetOwner() )
        {
            // Pay Cris, but don't touch the timer
            llSay(0, "Thank you for supporting SLU! Your payment has been passed along to Cristiano Midnight.");
            llGiveMoney(recipient, amount);
        }
        else
        {                
            //Pay Cris, and put 30 days on the clock
            llOwnerSay("Thank you for supporting SLU! Your payment has been passed along to Cristiano Midnight.");
            llGiveMoney(recipient, amount);
            last = llGetSubString(llGetTimestamp(), 0, 9);
            lastamount = amount;
            llSetTimerEvent(2592000); // Starts 30-day timer
        }
    }

    timer()
    {
        llInstantMessage(llGetOwner(), "Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);
        llSetTimerEvent(86400); // Resets timer to remind again in 1 day
    }

}
__________________
Philip 3:16
For Rosedale so loved the grid, that he rezzed his only begotten Avatar, that whosoever believeth in him shall not crash, but have eternal Second Life.

Last edited by Samantha Poindexter; 05-28-2012 at 11:25 PM. Reason: Changed notification method to llInstantMessage, per Alchemy's comment below
Samantha Poindexter is offline   Reply With Quote
1 User Said Yay!:
1 User Said Thanks:
Old 05-28-2012, 11:15 PM   #2 (permalink)
And you know that
 
bladyblue's Avatar
Play the game
 
Join Date: Jul 2007
Location: The Realm of Rygeon
Posts: 4,748
My Mood:
SL Join Date: February 2005
Client: Firestorm
Send a message via MSN to bladyblue Send a message via Yahoo to bladyblue Send a message via Skype™ to bladyblue
I bought a device that did this in 2010. It was called a membership kiosk. Set the notecard with their name and time sequence of donation.

Once they pay the chosen amount the first time, the owner can set the reminder intervals. If someone doesn't renew their subscription within two months (or whatever time you set) the person will be dropped from active membership.

You can add your own image.
__________________
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time... like tears in the rain...Time to die.-Roy Batty
bladyblue is offline   Reply With Quote
Old 05-28-2012, 11:16 PM   #3 (permalink)
Senior Member

*SLU Supporter*
 
Samantha Poindexter's Avatar
 
Join Date: Jun 2009
Posts: 1,012
SL Join Date: February 13, 2006
Business: Samantha's Shirts
Client: Cool VL Viewer 1.26.8

Awards: 1
Best Drama Summary 
I did have a feeling I was reinventing the wheel.

(But this is a specialized wheel, coded to go only down one specific road! Doesn't that count for anything? ...no? Never mind.)

Samantha Poindexter is offline   Reply With Quote
1 User Hugged You:
Old 05-28-2012, 11:19 PM   #4 (permalink)
And you know that
 
bladyblue's Avatar
Play the game
 
Join Date: Jul 2007
Location: The Realm of Rygeon
Posts: 4,748
My Mood:
SL Join Date: February 2005
Client: Firestorm
Send a message via MSN to bladyblue Send a message via Yahoo to bladyblue Send a message via Skype™ to bladyblue
It was the only one I ever found that would do that simple task.

But it would call for members to log onto SL and pay the kiosk every 30 days. I'm not sure if it takes PayPal.
bladyblue is offline   Reply With Quote
Old 05-28-2012, 11:20 PM   #5 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Nice script, though there are two caveats here:

1 Minor: llSetTimerEvent isn't exact in its timer-ness, and is affected by lag. So "30 days" won't really be "30 days" exactly, and can probably be off some days.

1 Major:
This line will only work if the owner happens to be in the same sim as the object when the timer is up:
llOwnerSay("Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);

In order for this to work wherever the owner is, replace the llOwnerSay line with this:
llInstantMessage(llGetOwner(), "Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);

--------------

Thus ends my revenge for all the instruction manuals I've written which Samantha has marked red ink all over! (And, made them better in the process. *hugz Sam*)

Alchemy

Quote:
Originally Posted by Samantha Poindexter View Post
I'm going to start with a bunch of disclaimers that may end up being longer than the script itself.

This may not be of any use to anybody else, but it was something I wanted, and I thought I might perhaps not be alone.

I wanted an object that would do the following things:
  1. Accept L$ donations to SLU and pass them along to Cris
  2. Remind me after 30 days had gone by that it was probably time to do it again.
(Item #1 would save me the five valuable seconds it would take me to find "Cristiano Midnight" in Search. On the other hand, while item #2 could just as easily been designed to automatically debit my account every 30 days, I don't keep a lot of cash on my avatar, and an unexpected payment could be problematic. This compromise fits my particular needs.)

I am not really a scripter, so I followed my usual approach of taking an existing script that was somewhere in the right ballpark (in this case, my SLU shirt vendor), stripping out everything that didn't do what I wanted here (about 95% of it), and then filling in whatever else was needed. There are probably bits that could be more efficient.

It occurred to me while testing this that I ought to allow people other than the object's owner to donate to SLU as well, without affecting the reminders sent to the owner. And that the owner should be able to check when their own last payment was made. In other words, some slight feature bloat happened.

Finally, note that this script requires you to grant permission to take L$ from your account and give it to somebody else, because, you know, that's what it's for. Caveat avatar, check the code, and all that.

Code:
// Support SLU!
string last = "never. For shame!";
integer lastamount = 0;
key recipient = "0d2d7814-8b2d-4db1-81b8-96b507104e89"; // Cris

default
{
    state_entry()
    {
        //get permission to give Cris the L$
        llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
        } 


    touch_start(integer total_number)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            llOwnerSay("Your last donation, of L$" + (string)lastamount + ", was " + last);
        }
        else
        {
            llSay(0, "Pay this object to support SLU!");
        }
    
    } 
    
    money(key id, integer amount)
    {
        if ( id != llGetOwner() )
        {
            // Pay Cris, but don't touch the timer
            llSay(0, "Thank you for supporting SLU! Your payment has been passed along to Cristiano Midnight.");
            llGiveMoney(recipient, amount);
        }
        else
        {                
            //Pay Cris, and put 30 days on the clock
            llOwnerSay("Thank you for supporting SLU! Your payment has been passed along to Cristiano Midnight.");
            llGiveMoney(recipient, amount);
            last = llGetSubString(llGetTimestamp(), 0, 9);
            lastamount = amount;
            llSetTimerEvent(2592000); // Starts 30-day timer
        }
    }

    timer()
    {
        llOwnerSay("Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);
        llSetTimerEvent(86400); // Resets timer to remind again in 1 day
    }

}
__________________
<-- 4Kittens
Co-Owner of Four Kittens of the Apocalypse!
http://slurl.com/secondlife/Penning/81/110/79
Alchemy Epstein is offline   Reply With Quote
1 User Said Thanks:
Old 05-28-2012, 11:22 PM   #6 (permalink)
Hive Mind Director
 
Cristiano's Avatar
Amish Mafia 4EVER
 
Join Date: Jun 2007
Location: Miami, FL
Posts: 23,080
My Mood:
SL Join Date: Dec 2002
Business: ANOmations
Client: Viewer 2
Blog Entries: 18
Send a message via Yahoo to Cristiano Send a message via Skype™ to Cristiano
I appreciate the script. I am working on something that will interface with the website to be able to send out reminders and update user groups when donations are made, that will be user managed through a page in the forum and can send out reminders via email or inworld im. The Paypal subscriptions on the site already automatically renew.
__________________
"For my part, I know nothing with any certainty, but the sight of the stars makes me dream" - Vincent Van Gogh


Cristiano is online now   Reply With Quote
1 User Said Yay!:
2 Users Said Thanks :
Old 05-28-2012, 11:24 PM   #7 (permalink)
Senior Member

*SLU Supporter*
 
Samantha Poindexter's Avatar
 
Join Date: Jun 2009
Posts: 1,012
SL Join Date: February 13, 2006
Business: Samantha's Shirts
Client: Cool VL Viewer 1.26.8

Awards: 1
Best Drama Summary 
Re: time dilation. Close enough for jazz?

Re: wrong method of notifying the owner. Oops. Good catch! I'll edit that in.
Samantha Poindexter is offline   Reply With Quote
1 User Said Thanks:
Old 05-28-2012, 11:27 PM   #8 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Quote:
Originally Posted by Samantha Poindexter View Post
Re: time dilation. Close enough for jazz?
Should be fine.

Quote:
Re: wrong method of notifying the owner. Oops. Good catch! I'll edit that in.
No probs!

Alchemy "Please Pray to the Linden Gods for the Safety of my account" Epstein
Alchemy Epstein is offline   Reply With Quote
Old 05-28-2012, 11:29 PM   #9 (permalink)
*blink*

*SLU Supporter*
 
Soen Eber's Avatar
don't need status
 
Join Date: Oct 2009
Location: Minneapolis, Minnesota, USA
Posts: 3,372
My Mood:
Since IMs routinely get capped/lost, its probably better to send an email.
Soen Eber is online now   Reply With Quote
1 User Said Thanks:
Old 05-28-2012, 11:42 PM   #10 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Quote:
Originally Posted by Soen Eber View Post
Since IMs routinely get capped/lost, its probably better to send an email.
OK, so if you'd like to do something like that, go with this instead of llOwnerSay or llInstantMessage:

llEmail( string address, string subject, string message );

Example:

llEmail("youremailaddress@email.com", "SLU Donation Reminder", "Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);

Alchemy
Alchemy Epstein is offline   Reply With Quote
Old 05-28-2012, 11:49 PM   #11 (permalink)
Senior Member

*SLU Supporter*
 
Samantha Poindexter's Avatar
 
Join Date: Jun 2009
Posts: 1,012
SL Join Date: February 13, 2006
Business: Samantha's Shirts
Client: Cool VL Viewer 1.26.8

Awards: 1
Best Drama Summary 
I seem to do okay with llInstantMessage going to my e-mail... plus using llEmail would add a hard-coded value that would need to be changed by any given owner, so I think I'm going to leave the version in the first post as-is. But I do appreciate the insight and the example code! I've never used a script to send e-mail, and it's nice to know how.
Samantha Poindexter is offline   Reply With Quote
Old 05-29-2012, 12:55 AM   #12 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Oh, I agree with your approach completely. The example wasn't so much for you as it was for anyone who wanted to change it in their own version.

Alchemy

Quote:
Originally Posted by Samantha Poindexter View Post
I seem to do okay with llInstantMessage going to my e-mail... plus using llEmail would add a hard-coded value that would need to be changed by any given owner, so I think I'm going to leave the version in the first post as-is. But I do appreciate the insight and the example code! I've never used a script to send e-mail, and it's nice to know how.
Alchemy Epstein is offline   Reply With Quote
Old 05-29-2012, 10:26 AM   #13 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Ahh, caught something else here.

In the below snippets, before each of the llSetTimerEvent statements put "llSetTimerEvent(0.0)";

llSetTimerEvent does not immediately remove any old timer; so if it was previously on a 30-day timer when it set it to 1 day, then it'll do a 30-day timer again and then a 1-day. Same principle in reverse. Setting llSetTimerEvent(0.0) clears the timer, however, so that the new timer will take effect immediately.

Alchemy

Quote:
Originally Posted by Samantha Poindexter View Post
//Pay Cris, and put 30 days on the clock
llOwnerSay("Thank you for supporting SLU! Your payment has been passed along to Cristiano Midnight.");
llGiveMoney(recipient, amount);
last = llGetSubString(llGetTimestamp(), 0, 9);
lastamount = amount;
llSetTimerEvent(2592000); // Starts 30-day timer
and

Quote:
timer()
{
llInstantMessage(llGetOwner(), "Isn't it time you supported SLU? Your last donation, of L$" + (string)lastamount + ", was " + last);
llSetTimerEvent(86400); // Resets timer to remind again in 1 day
}
Alchemy Epstein is offline   Reply With Quote
Old 05-29-2012, 12:15 PM   #14 (permalink)
Senior Member

*SLU Supporter*
 
Samantha Poindexter's Avatar
 
Join Date: Jun 2009
Posts: 1,012
SL Join Date: February 13, 2006
Business: Samantha's Shirts
Client: Cool VL Viewer 1.26.8

Awards: 1
Best Drama Summary 
Quote:
Originally Posted by Alchemy Epstein View Post
llSetTimerEvent does not immediately remove any old timer; so if it was previously on a 30-day timer when it set it to 1 day, then it'll do a 30-day timer again and then a 1-day. Same principle in reverse. Setting llSetTimerEvent(0.0) clears the timer, however, so that the new timer will take effect immediately.
Hmm. I actually tested this using 30 seconds the first time, and 10 seconds on the subsequent one, and it seemed to work as intended, in both directions?
Samantha Poindexter is offline   Reply With Quote
Old 05-29-2012, 01:17 PM   #15 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,225
My Mood:
SL Join Date: late 04... that account is deleted now
I also haven't seen that happen... in either direction... bump timers are common and rely on the bumping the timer forward before the event queues, so that it's always set to trigger X seconds from the last event that setup a timer trigger (such as notecard readers)... and I've used interrupt timers in a similar way setting the current timer down to 0.01 so that the timer will queue immediately without issue.

all that said I've never used timers that change between call times with such large scales (other than 0.0/some value < 5 minutes)... it's possible that region restarts might possibly interfere on that scale, but that would be a separate issue

Quote:
Originally Posted by Cristiano View Post
I appreciate the script. I am working on something that will interface with the website to be able to send out reminders and update user groups when donations are made, that will be user managed through a page in the forum and can send out reminders via email or inworld im. The Paypal subscriptions on the site already automatically renew.
so THAT'S what the LSL server question was about?
__________________
- These eyes can do more than see
Quote:
Originally Posted by Cajsa Lilliehook View Post
It's not enough to care about liberty if the only liberty you care about is your own.
Quote:
Originally Posted by Jupiter Firelyte View Post
Why doesn't anyone ever ask, "What is the real meaning of the winter solstice?"
Quote:
Originally Posted by Eboni Khan View Post
Thanks for being passive agressive.
Void is offline   Reply With Quote
Old 05-30-2012, 08:04 AM   #16 (permalink)
Mad Scripter
 
Join Date: Mar 2011
Posts: 27
My Mood:
Quote:
Originally Posted by Void View Post
I also haven't seen that happen... in either direction... bump timers are common and rely on the bumping the timer forward before the event queues, so that it's always set to trigger X seconds from the last event that setup a timer trigger (such as notecard readers)... and I've used interrupt timers in a similar way setting the current timer down to 0.01 so that the timer will queue immediately without issue.
Hmmm.... It's possible I'm misremembering something, although I swear I had issues with this at one time. However, since it's been tested backwards and forwards, then nevermind *smiles*

Alchemy
Alchemy Epstein is offline   Reply With Quote
Old 05-30-2012, 10:41 AM   #17 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,225
My Mood:
SL Join Date: late 04... that account is deleted now
it's possible it was a bug at one time or really long timers that got affected by resets may have looked that way... doesn't seem to be a current issue though.
Void is offline   Reply With Quote
Old 05-30-2012, 11:11 AM   #18 (permalink)
Nasty Brit
 
Innula Zenovka's Avatar
Wants *things*
 
Join Date: May 2009
Posts: 6,976
SL Join Date: 17 June 2007
Business: Something Spunky
What about sim restarts? I'd always thought those pause the timer while the sim is offline -- that is, that if you call llSetTimerEvent(43200.0) at 0900 and the sim goes offline for an hour at some point during the next 12 hours, then the timer event fires at 2200 rather than 2100.

Those might explain why long timer events develop delays, though I've never actually tested to see what happens; I've always assumed that I need to recalculate and reset my long timers on CHANGED_REGION_START, and I'm wondering, now, after reading Kelly's recent comments in reply to questions about region idling and timers, what actually does happen.

I'll try to remember to set something up to check next week when they're doing restarts, unless anyone knows for sure.
__________________
Innula Zenovka is online now   Reply With Quote
Old 05-30-2012, 01:24 PM   #19 (permalink)
*blink*

*SLU Supporter*
 
Soen Eber's Avatar
don't need status
 
Join Date: Oct 2009
Location: Minneapolis, Minnesota, USA
Posts: 3,372
My Mood:
If you're actually using the timer to start when they donate and run for 30 days you're putting yourself at risk for restarts and other fun stuff. Its safer to have the script remember the time as a unix_time that can be constantly polled against with the timer.

Try this instead (this is semi-pseudocode, so you might have to look up some functions, and I haven't tested any of this). I'm still retired from scripting by the way

Code:
// in global variable section before declaring the default state
integer unix_time;
integer unix_time_last_donated;
integer last_nagged;
integer days_between_nags = 1;
float timer_interval = 900; // fifteen minutes should be enough (not sure if this is an int)

//  After the llGiveMoney function
// Conditions: money must come from object owner
    unix_time_last_donated = llGetUnixTime();
    llSetTimerEvent(timer_interval);
    // also trap day/date/time of donation to use in your text response

// New function, stick it ahead of state declaration
integer days_since()
{
    unix_time = llGetUnixTime();
    // this checks how many days have passed. Don't forget parenthesis!
    float days = (unix_time - unix_time_last_donated) / (60*60*24);
    return (integer)days;
}

// Add an on_rez event in case of restarts and other carelessness
on_rez()
{
    // only start timer if owner has previously donated
    if (unix_time_last_donated != 0) {
        llSetTimerEvent(timer_interval);
    }
}

// in touch event
// condition: owner has touched
    integer days = days_since();
    llWhisper("You last donated to SLU "+(string)days+" days ago";
    if (days > 30) {
        llWhisper("Isn't it time you donated again?");
    }

// timer event
    // don't do anything if owner hasn't donated yet
    if (unix_time_last_donated > 0) {
        integer days = days_since();
        integer unix_time = llGetUnixTime();
        if (days > 30) {
            if ((last_nagged == 0) || (last_nagged > (60*60*24*days_between_nags)) {
                last_nagged = llGetUnixTime();
                // IM owner a donation reminder
            } // ... if ((last_naged == 0...
        } // ... if (days > 30...
    } // ... if (unix_time_last_donated...
You can also opt to save unix_time_last_donated to the description field and read it in the on_rez event to let the reminder object remember after a script reset after clearing. You'll probably want to save it as unix_time_last_donated/(60*60*24) in that case so if the owner mouses over it they can see how many days have passed with a hover instead of having to click on it. You'll undo the division when you read it back in on on_rez
Soen Eber is online now   Reply With Quote
Old 05-30-2012, 04:34 PM   #20 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,225
My Mood:
SL Join Date: late 04... that account is deleted now
Quote:
Originally Posted by Innula Zenovka View Post
What about sim restarts? I'd always thought those pause the timer while the sim is offline -- that is, that if you call llSetTimerEvent(43200.0) at 0900 and the sim goes offline for an hour at some point during the next 12 hours, then the timer event fires at 2200 rather than 2100.

Those might explain why long timer events develop delays, though I've never actually tested to see what happens; I've always assumed that I need to recalculate and reset my long timers on CHANGED_REGION_START, and I'm wondering, now, after reading Kelly's recent comments in reply to questions about region idling and timers, what actually does happen.

I'll try to remember to set something up to check next week when they're doing restarts, unless anyone knows for sure.
presumably from Kelly's remarks, timer events that should queue while the region is down should queue immediately after it comes back up, and one that went down and came back up before needing to queue should be unaffected... but I haven't tested that.

@Soen:
It's slightly less work to save the projected subscription date, rather than the date last paid... that way there's not extra math comparing it to unix time that has to be done on each check. not an important issue here, but on much shorter timescales, or much heavier use, it can help. (it also results in a count down rather than a count up)
Void is offline   Reply With Quote
2 Users Said Thanks :
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On