Difference between revisions of "LlTransferLindenDollars"

From Second Life Wiki
Jump to navigation Jump to search
m (Added notation to script comments regarding L$ display results on the viewer.)
m (Replaced old <LSL> block with <source lang="lsl2">)
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{LSL_Function
{{LSL_Function
|inject-2={{LSL_Function/permission|PERMISSION_DEBIT|grant=the owner}}{{LSL Function/avatar|destination}}
|inject-2={{LSL_Function/permission|PERMISSION_DEBIT|grant=the owner}}{{LSL Function/avatar|destination}}
{{Issues/VWR-28201}}{{Issues/SVC-7623}}
|func_id=?|func_sleep=0.0|func_energy
|func_id=?|func_sleep=0.0|func_energy
|func=llTransferLindenDollars
|func=llTransferLindenDollars
|return_type=key|return_text=used in a matching [[transaction_result]] event for the success or failure of the transfer. If the transaction is successful, this key will show in the [https://secondlife.com/my/account/transactions.php transaction history].
|return_type=key|return_text=used in a matching [[transaction_result]] event for the success or failure of the transfer. If the transaction is successful, this key will show in the [https://secondlife.com/my/account/transactions.php transaction history].
|p1_type=key|p1_name=destination
|p1_type=key|p1_name=destination
|p2_type=integer|p2_name=amount|p2_desc=number of L$, must be greater than zero, ('''amount''' &gt; 0)
|p2_type=integer|p2_name=amount|p2_desc=number of L$, must be greater than zero, ({{LSLP|amount}} &gt; 0)|p2_hover=number of L$, must be greater than zero, ('amount' &gt; 0)
|func_desc=Transfer '''amount''' of L$ money from script owner to '''destination''' avatar.
|func_desc=Transfer {{LSLP|amount}} of L$ money from script owner to {{LSLP|destination}} avatar.
|func_footnote=If you aren't going to use the return value or the resulting [[transaction_result]] event consider using [[llGiveMoney]] instead of this function.
|func_footnote=If you aren't going to use the return value or the resulting [[transaction_result]] event consider using [[llGiveMoney]] instead of this function.
|spec
|spec
Line 14: Line 15:
*Once a script has the [[PERMISSION_DEBIT]] permission it can empty an account of L$.
*Once a script has the [[PERMISSION_DEBIT]] permission it can empty an account of L$.
**Fraud & theft are both {{LL|TOS}} violations and crimes. Misuse this function and you risk being banned and legal action. In addition LL may freeze the accounts of anyone the money is transferred to and restore it to it's rightful owners. This may involve retrieving it from third party exchanges and accounts on those exchanges being frozen. The system is not designed to be friendly towards fraud.
**Fraud & theft are both {{LL|TOS}} violations and crimes. Misuse this function and you risk being banned and legal action. In addition LL may freeze the accounts of anyone the money is transferred to and restore it to it's rightful owners. This may involve retrieving it from third party exchanges and accounts on those exchanges being frozen. The system is not designed to be friendly towards fraud.
|examples=<lsl>/*
|examples=<source lang="lsl2">
* A simple piggy bank, anyone can pay in money and anyone can click it to get money out.
// Pay 100 L$ to Fred Bloggs when he touches this prim
*
// Die if the transfer of funds was successful, else keep running
* TO DO:
*  - handle different errors differently based upon CSV output
*
* original by Strife Onizuka
*
* modified by Kireji Haiku:
*  - because weird things happen in LSL when using more than one state
*  - one should say thanks when being payed
*  - added 0 L$ payment when bank is empty, to show failed payment notifications
*  - added target UUID and L$ amount into transaction history, too
*
* Note from Traven Sachs:
* In testing this script using an account with no funds - it has been noted that when the INSUFFICIENT FUNDS
* error occurs on Transaction Results that the Display of L$ on the account attempting to transfer funds will
* read as -1 on some viewers, even if the account has funds less than the transaction amount available to it.
* (i.e. if account has 7L and attempts to pay 10L the viewer display will read -1 L until the next L$ transaction
* occurs that is actually valid.  Don't know if this is a viewer glitch or back end glitch but felt it should
* be mentioned.)
*/


integer hasBeenGrantedDebitPerms;
string  Recipient = "Fred Bloggs";      // Authorised recipient
integer Amount = 100;                   // Amount to pay Fred when he touches the prim


integer amountGivenAwayOnClick;
integer DebitPerms;
integer totalLindenDollarsInBank;
key     TransactionID=NULL_KEY;
 
list listOfTransactionRecords;
 
update_floattext()
{
     string floattext = "I have no L$ to give away :(";
 
    if (amountGivenAwayOnClick <= totalLindenDollarsInBank
        && hasBeenGrantedDebitPerms)
    {
        floattext = "I have L$ "+ (string)totalLindenDollarsInBank + " to give away!";
    }
 
    llSetText(floattext, <1.0, 1.0, 1.0>, (float)TRUE);
}


default
default
{
{
     on_rez(integer start_param)
     state_entry()
     {
     {
         llResetScript();
         // Ask the owner for permission to debit their account
        llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
     }
     }


 
     run_time_permissions (integer perm)
     changed(integer change)
     {
     {
         if (change & CHANGED_OWNER)
         if (perm & PERMISSION_DEBIT)
             llResetScript();
             DebitPerms = TRUE;
     }
     }


     state_entry()
     touch_start(integer num_detected)
     {
     {
         // how much money to give away each time?
         if (!DebitPerms)
 
            return;  // Cannot proceed - debit permissions not granted
         amountGivenAwayOnClick = 10;
         if (llDetectedName(0) != Recipient)
 
            return; // unauthorised person is touching - ignore
        // how much money do we initially "have" in the bank?
         if (TransactionID != NULL_KEY)
 
            return; // waiting on previous transaction to complete/fail
         totalLindenDollarsInBank = 50;


        update_floattext();
         key id = llDetectedKey(0);
 
         TransactionID = llTransferLindenDollars(id, Amount);
        // request permissions to give away money, otherwise this won't work
 
         key owner = llGetOwner();
         llRequestPermissions(owner, PERMISSION_DEBIT);
     }
     }


     touch_start(integer num_detected)
     transaction_result(key id, integer success, string data)
     {
     {
         // if the script has been granted debit permissions
         if (id != TransactionID)
         if (hasBeenGrantedDebitPerms)
            return;          // Ignore if not the expected transaction
       
         if (success)
         {
         {
             key id = llDetectedKey(0);
             llOwnerSay( "Transfer of L$ to " + Recipient + " was successful");
 
            llSleep(1.0);
            // if we have at least as much money in the bank as we would be giving away
             llDie();         // Die so Fred can't keep taking money
            if (amountGivenAwayOnClick <= totalLindenDollarsInBank)
            {
                // we add the transaction ID, the target avatar UUID and the L$ amount to a list
                listOfTransactionRecords = (listOfTransactionRecords = []) + listOfTransactionRecords + llTransferLindenDollars(id, amountGivenAwayOnClick) + id + amountGivenAwayOnClick;
 
                // we take the money from the bank
                totalLindenDollarsInBank -= amountGivenAwayOnClick;
             }
            else
            {
                // will not work, cause paying 0 L$!
                // will send a "failed payment" notification!
                // only for DEMO purposes, usually you should do something like:
                // llSay(PUBLIC_CHANNEL, "Sorry, no money in the bank!");
                // instead !!!
 
                listOfTransactionRecords = (listOfTransactionRecords = []) + listOfTransactionRecords + llTransferLindenDollars(id, 0) + id + 0;
            }
         }
         }
 
         else
         update_floattext();
    }
 
    money(key id, integer amount)
    {
        // someone payed the bank!
 
        totalLindenDollarsInBank += amount;
 
        // be nice, say thanks
        llInstantMessage(id, "Thanks a bunch!");
 
        update_floattext();
    }
 
    transaction_result(key id, integer success, string data)
    {
        integer index = llListFindList(listOfTransactionRecords, [id]);
 
        //if the ID was found in our list
        if (~index)
         {
         {
             // if payment failed, give notice
             llOwnerSay( "Transfer of L$ failed");
            if (!success)
            TransactionID = NULL_KEY;
            {
             // Keep the script running so Fred can try again, clear TransactionID to allow a new attempt
                key targetUUID = llList2Key(listOfTransactionRecords, index + 1);
                integer amountNotPayed = llList2Integer(listOfTransactionRecords, index + 2);
 
                llSay(PUBLIC_CHANNEL, "\n \nSorry, somehow the transaction has failed!"
                    + "\ntransaction ID: " + (string)id
                    + "\ntarget UUID: " + (string)targetUUID
                    + "\namount not payed: " + (string)amountNotPayed);
 
                // if the amount that wasn't payed is more than 0 L$, put the money back into the bank
                if (amountNotPayed)
                    totalLindenDollarsInBank += amountNotPayed;
            }
 
             // remove the entry again [transaction ID, target UUID, L$ amount]
            listOfTransactionRecords = llDeleteSubList(listOfTransactionRecords, index, index + 2);
         }
         }
        // total amount could have changed again...
        update_floattext();
     }
     }
 
}
    run_time_permissions (integer perm)
</source>
    {
|complex_examples=
        // when owner granted debit perms, enable piggy bank functionality
{{LSL DefineRow||[[Simple Piggy Bank]]|}}
        if(perm & PERMISSION_DEBIT)
            hasBeenGrantedDebitPerms = TRUE;
 
        update_floattext();
    }
}</lsl>
|helpers
|helpers
|also_functions=
|also_functions=
Line 187: Line 89:
|cat4
|cat4
|cat5
|cat5
|history = Date of Release  [[ Release_Notes/Second_Life_Server/11#11.12.03.246118 | 03/12/2011 ]]
}}
}}

Latest revision as of 11:12, 22 January 2015

Summary

Function: key llTransferLindenDollars( key destination, integer amount );

Transfer amount of L$ money from script owner to destination avatar.
Returns a key used in a matching transaction_result event for the success or failure of the transfer. If the transaction is successful, this key will show in the transaction history.

• key destination avatar UUID
• integer amount number of L$, must be greater than zero, (amount > 0)

To run this function the script must request the PERMISSION_DEBIT permission with llRequestPermissions and it must be granted by the owner. If you aren't going to use the return value or the resulting transaction_result event consider using llGiveMoney instead of this function.

Caveats

Permissions
  • Do not depend upon the auto-grant status of permissions. Always use the run_time_permissions event.
  • If the script lacks the permission PERMISSION_DEBIT, the script will shout an error on DEBUG_CHANNEL and the operation fails (but the script continues to run).
  • If PERMISSION_DEBIT is granted by anyone other than the owner, then when the function is called an error will be shouted on DEBUG_CHANNEL.
  • Once the PERMISSION_DEBIT permission is granted there is no way to revoke it except from inside the script (for example, with a new llRequestPermissions call) or the script is reset or deleted.
  • An object cannot pay another object.
  • Objects deeded to groups cannot give money (the permission cannot be granted).
  • Use is limited to 30 payments in a 30 second interval for all scripts owned by that resident on a region. Sustained overage will produce a script error and halt payments while the rate remains excessive. Historically, faster payments have failed intermittently.
  • Once a script has the PERMISSION_DEBIT permission it can empty an account of L$.
    • Fraud & theft are both Linden Lab violations and crimes. Misuse this function and you risk being banned and legal action. In addition LL may freeze the accounts of anyone the money is transferred to and restore it to it's rightful owners. This may involve retrieving it from third party exchanges and accounts on those exchanges being frozen. The system is not designed to be friendly towards fraud.

Examples

// Pay 100 L$ to Fred Bloggs when he touches this prim
// Die if the transfer of funds was successful, else keep running

string  Recipient = "Fred Bloggs";      // Authorised recipient
integer Amount = 100;                   // Amount to pay Fred when he touches the prim

integer DebitPerms;
key     TransactionID=NULL_KEY;

default
{
    state_entry()
    {
        // Ask the owner for permission to debit their account
        llRequestPermissions(llGetOwner(), PERMISSION_DEBIT);
    }

    run_time_permissions (integer perm)
    {
        if  (perm & PERMISSION_DEBIT)
            DebitPerms = TRUE;
    }

    touch_start(integer num_detected)
    {
        if (!DebitPerms)
            return;  // Cannot proceed - debit permissions not granted
        if (llDetectedName(0) != Recipient)
            return;  // unauthorised person is touching - ignore
        if (TransactionID != NULL_KEY)
            return;  // waiting on previous transaction to complete/fail

        key id = llDetectedKey(0);
        TransactionID = llTransferLindenDollars(id, Amount);
    }

    transaction_result(key id, integer success, string data)
    {
        if (id != TransactionID)
            return;          // Ignore if not the expected transaction
        
        if (success)
        {
            llOwnerSay( "Transfer of L$ to " + Recipient + " was successful");
            llSleep(1.0);
            llDie();          // Die so Fred can't keep taking money
        }
        else
        {
            llOwnerSay( "Transfer of L$ failed");
            TransactionID = NULL_KEY;
            // Keep the script running so Fred can try again, clear TransactionID to allow a new attempt
        }
    }
}

Complex Examples

•  Simple Piggy Bank

Notes

  • released on main server channel on 3-Dec-2011

See Also

Events

•  run_time_permissions Permission receiving event
•  transaction_result
•  money

Functions

•  llGetPermissions Get the permissions granted
•  llGetPermissionsKey Get the agent who granted permissions
•  llRequestPermissions Request permissions
•  llGiveMoney
•  llSetPayPrice

Articles

•  Script permissions

Deep Notes

History

Date of Release 03/12/2011

Signature

function key llTransferLindenDollars( key destination, integer amount );