Jump to content

help with PERMISSION_DEBIT flag on llRequestPermissions() and states


Jaymes Capalini
 Share

You are about to reply to a thread that has been inactive for 4102 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I have an item that I would like to distribute to others on a free or discounted basis, so they can put it out to sell items from.  Essentially an affiliate vendor (though it is, in fact, a soda machine).

I have two states in my script.  One state is default, the other is "Money".

The default state has a llRequestPermissions(llGetOwner(),PERMISSION_DEBIT) command in state_entry().

It also has a run_time_permissions(integer perm) section that checks the value of perm & PERMISSION_DEBIT.  If TRUE, it changes the state to "Money".

The Money state has a money section in it to allow the item to accept payment, which puts a product delivery script into motion.

All this works fine, the first time I run it after saving changes to my script. It comes up in the default state, requests debit permission, won't accept money if the user doesn't allow PERMISSION_DEBIT, changes to the Money state if they do.  Everything is fine.

HOWEVER... I noticed that if I then go and edit the item, and reset scripts, it then reissues the request for debit permissions, but regardless of whether the owner grants debit permissions, it still allows money to be paid to the object. 

This is very odd, because they object only has a "money()" section in the "Money" state.  So, I don't know why it is accepting money at all.  And it can't be in the "Money" state itself, because it doesn't execute any of the statements in the money() section.

To further confuse it, there is a llSetPayPrice() function in the "Money" state that limits the input to 10L.  This also seems to be working in this quasi state, because the unit will still only accept 10L.  But again, it does nothing when paid.

Anyone have any ideas as to what to do about this?

 

 

Link to comment
Share on other sites

Put a statement in state_entry of state Money that says llSetClickAction(CLICK_ACTION_PAY) .  Then wherever you exit to state default (from your money event and from your timeout timer event), put the reverse, llSetClickAction(CLICK_ACTION_TOUCH).  That should make it so that the Pay option is only called on left click when you are actually in state Money.  Then, capture the buyer's UUID in the touch_end event in state default and do a check in the money event in state Money.  If the person paying is not the same person who touched, return the money.

Frankly, having written that, I very rarely put PERMISSION_DEBIT in a vendor script.  If you write the script well enough, the buyer should only have one option (or a small number of options) in the Pay window. There shouldn't be any reason to give a refund or make change.  If there is, it's because they have tried to game the vendor, and they can try and explain it when they complain and want a refund.

Link to comment
Share on other sites

That sort of addresses the issue.  Yes, I do have the object set to pay when left-clicked, and I did wonder about whether that could be changed.  So thanks for that tip!  :matte-motes-big-grin-wink:

I do limit what the customer is allowed to pay so that they can only pay the actual price of the item.  So, I don't really need PERMISSION_DEBIT for that.

However, I do use PERMISSION_DEBIT to split money between the creator (i.e. me) and the owner of the object (whoever wants to put one out).  The purpose of my script is to only take money and distribute product if the owner of the object has agreed to split the proceeds.

What is not making sense to me is that the script is acting like there is a money handler in the default state, when there clearly is not.  

What I have done for now is similar to what you suggest but goes one step further.  I have set "llSetPayPrice(PAY_HIDE, [0, PAY_HIDE, PAY_HIDE, PAY_HIDE]);" in the state_entry of the default state, so that even if someone does attempt to pay, it doesn't allow them to as all the amounts are hidden and no manual payment can be done.  changing the click action would only prevent them from paying with a left click, not at all. 

This isn't really a solution, but it is an effective bandaid I suppose.  At least I'm not taking money from people and giving them nothing in return.  But it's not the solution i'm looking for.  The object shouldn't be trying to take money at all.


This seems to be a bug in the money handling of SL.  It is acting sort of like an object property setting (i.e. llSetText) where once the setting is made, you have to issue a new command to take it off.  That's ok, but what command would take it off?

Link to comment
Share on other sites

Without looking at the script, it's hard for me to guess why that's happening.  If it were my script, though, I would insert some strategic llOwnerSay statements in a few spots to be sure that the script is going where you think it is.  It sounds as if you are not exiting to state default, but are still in state Money.

When I create a vendor, I usually put configuration stuff into state default and make sure that it only responds to me, if it requires a response at all.  Then, I transfer execution to a run state that watches for customers, with no way to get back to state default -- or with only a single trap door that responds to me.  While the vendor is running, it can move back and forth between my running state and a state Money that is like yours. That way, nobody can mess with the configuration but me.

Link to comment
Share on other sites

Yep, that is basically the approach I have taken.  There is nothing in the default state except a check for debit permissions.  It only moves to state Money if those permissions are granted.


I know it seems like it is still in state Money, but it isn't.  it is executing commands (like setting the llSetPayPrice to zero) that are only in the default state.  Also it is firing the request for debit permissions, which also only exists in the default state.

Here is the script itself:

 

integer intCorrectAmt = 10;integer intShareAmt = 1;default //not accepting payment{    state_entry()    {        llSetPayPrice(PAY_HIDE, [0, PAY_HIDE, PAY_HIDE, PAY_HIDE]);        llRequestPermissions(llGetOwner(),PERMISSION_DEBIT);            }    run_time_permissions(integer perm)    {        if (PERMISSION_DEBIT & perm)        {            state Money;        }    }}state Money{    state_entry()    {        llSay(0,"Now accepting money!");        llSetPayPrice(PAY_HIDE, [10, PAY_HIDE, PAY_HIDE, PAY_HIDE]);        llSetTimerEvent(10);    }        money(key id, integer amount)    {        if (amount == intCorrectAmt)        {            llGiveMoney("44b47a0a-90d2-444c-b30e-775f27e03e86",intShareAmt);            //Here I fire a llMessageLinked function that allows other scripts in the objet to take over.            llSay(0,"Thank you!");        }        else        {            llGiveMoney(id, amount);        }    }}

 NOTE:  As you said, it shouldn't really require the check to ensure that the money paid was the correct amount.  I threw that in as a just in case.

Link to comment
Share on other sites

That's odd.  It works fine for me.  There's no way that your script ever returns to state default unless you reset it.  Here's a slightly modified version of what you wrote:

integer intCorrectAmt = 10;integer intShareAmt = 1;key gSomeoneElse = "44b47a0a-90d2-444c-b30e-775f27e03e86";default //not accepting payment{    state_entry()    {        llOwnerSay("This is state default");//        llSetPayPrice(PAY_HIDE, [0, PAY_HIDE, PAY_HIDE, PAY_HIDE]);  //We don't need this here        llRequestPermissions(llGetOwner(),PERMISSION_DEBIT);            }    run_time_permissions(integer perm)    {        if (PERMISSION_DEBIT & perm)        {            state Money;        }    }}state Money{    state_entry()    {        llSetClickAction(CLICK_ACTION_PAY);        llSay(0,"Now accepting money!");        llSetPayPrice(PAY_HIDE, [10, PAY_HIDE, PAY_HIDE, PAY_HIDE]);//        llSetTimerEvent(10.0);  //This is not being used for anything    }        money(key id, integer amount)    {        if (amount == intCorrectAmt)        {            llGiveMoney(gSomeoneElse,intShareAmt);            //Here I fire a llMessageLinked function that allows other scripts in the objet to take over.            llSay(0,"Thank you!");        }        else        {            llGiveMoney(id, amount);        }    }}

 It does exactly what I would expect.  I only get the initial llOwnerSay message one time, before it requests permission and leaves state default forever.

Incidentally, just for comparison, take a look at http://community.secondlife.com/t5/LSL-Library/Split-Payment-Vendor/td-p/722093

Link to comment
Share on other sites

The llSetPayPrice line that you removed from default is actually my bandaid.  It keeps the unit from accepting money even after the weird state reset.

The llSetTimerEvent was left over from an earlier attempt to fix. :)

The script works great for me too, when have just edited the script and saved it.  No problems at all.

But when I reset all scripts in the item, from the build menu (Firestorm 4.3.1), it goes into the wonky semi default state that still allows payment.

Link to comment
Share on other sites

Ah, I see what's going on, and I apologize for a mistake on my part.  I was focused on the wrong end of the script.  If you have provided a llSetPayPrice statement with ANY value other than PAY_HIDE, then someone who right-clicks and selects the Pay option will get a Pay window.  The llSetPayPrice statement that you put into state default will create a bogus Pay window, because you gave ZERO as one of the options.  If you don't want any Pay window to show up at all while you are in state default, try

llSetPayPrice(PAY_HIDE,[PAY_HIDE,PAY_HIDE,PAY_HIDE,PAY_HIDE]);

Sorry about that.

BTW, the reason that your previous set price of L$10 persists even after the script is reset is that pay price is a prim property, like a sit target, a hover text, or a particle source. You have to set it with a script, but you also have to remove it with a script.  If you remove the script entirely, the last values in llSetPayPrice will still be there for anyone who clicks and selects the Pay option.

Link to comment
Share on other sites

Rolig:

Thank you for helping on this.  I really appreciate it. 

Unfortuantely that doesn't really address the core problem.  Setting all of the pay options to PAY_HIDE, and the way I had it (with one being "0") both did the same thing.

I have now changed it so that the default state returns the llSetPayPrice to it's default

llSetPayPrice(PAY_DEFAULT, [PAY_DEFAULT, PAY_DEFAULT, PAY_DEFAULT, PAY_DEFAULT]);

This does reset all the values back to what they should be.

However, it doesn't address the problem that the object is accepting money when there is no money section in the state it is in.  It still does that.

 

 

 

Link to comment
Share on other sites

OK... new information here.

I went and checked out your split script that you linked to earlier. 


Guess what.  Same thing happens.


Steps I'm taking:

  1. Edit the script, and change the split percent (gSplitPct), and key (gSplitKey).  Save the script.
  2. Test the script by Allowing Debit Permissions.  Result:  Left clicking allows me to pay 1,000 lindens.  This is split 75/25 as specified, with my alt (who is getting rich from all this).
  3. Now, reset the scripts in the object.
  4. This time choose "deny" on the Debit Permissions.
  5. The object still shows a payment option when i hover it.  When I left click, it still allows me to pay 1,000.  However, now the money does not split.
Link to comment
Share on other sites

I think this fixes it.   That is, it makes the object unpayable in state default after a reset.

integer intCorrectAmt = 10;integer intShareAmt = 1;key gSomeoneElse = "44b47a0a-90d2-444c-b30e-775f27e03e86";default //not accepting payment{    state_entry()    {        llOwnerSay("This is state default");     llSetPayPrice(PAY_HIDE, [ PAY_HIDE]);      llSetClickAction(CLICK_ACTION_TOUCH);        llRequestPermissions(llGetOwner(),PERMISSION_DEBIT);            }    run_time_permissions(integer perm)    {        if (PERMISSION_DEBIT & perm)        {            state Money;        }    }}state Money{    state_entry()    {        llSetClickAction(CLICK_ACTION_PAY);        llSay(0,"Now accepting money!");        llSetPayPrice(PAY_HIDE, [10, PAY_HIDE, PAY_HIDE, PAY_HIDE]);//        llSetTimerEvent(10.0);  //This is not being used for anything    }        money(key id, integer amount)    {        if (amount == intCorrectAmt)        {         //   llGiveMoney(gSomeoneElse,intShareAmt);            //Here I fire a llMessageLinked function that allows other scripts in the objet to take over.            llSay(0,"Thank you!");        }        else        {            llGiveMoney(id, amount);        }    }}

 

Link to comment
Share on other sites

That is incredibly spooky. It does not do that for me.  If there's a statement with all llSetPayPrice values set to PAY_HIDE, I cannot select a Pay option in state default at all.  The option is grayed out and no Pay window opens.

Do you have some other script in your object that has a llSetPayPrice statement in it?  Maybe a second copy of this same script, left over from earlier testing?

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4102 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...