Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

permissions ... wtf?

Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-01-2006 12:52
From: Damanios Thetan
What we need to know if this is a 'real' event triggered by llRequestPermissions or a 'rogue' event triggered by an automatic permissions change (llReleaseControls?).
If you need to know that, then you need to do something about it, like using a global to track whether you want something to happen if permissions are denied. Most of the time, though, you don't. Most of the stuff you'd be doing when you take permissions is stuff where ignoring a false negative is harmless.
From: someone
Agreed, except where it used to be enough to check this in the actual 'changed' event, it is now also required in the 'run_time_permissions' event.
True, it wasn't actually necessary to check the perms if you know what they're going to be. However, it was good coding practice to do it anyway. It's like checking the return value from opening a file, even when you know the file's gotta be there and readable because you couldn't have been called if it wasn't. If the API specifies that something can have multiple values, I automatically write my code to deal with that. It's a good habit to get into.

I'm still finding and fixing code that's broken by this, but none of it's mine.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-01-2006 12:54
From: Pericat Aquitaine
I am at my wits' end to capture this event and handle it; as the avatar is no longer attached, there's sod all I can do. Run-time is over. Fini. llAvatarOnSitTarget() is a null key. llGetOwner() isn't, but the errors (there are two of them, each time) have come and gone, and it's way late for me to toddle about asking for permissions on behalf of a boat owner no longer linked to her boat. Not that I haven't tried. Which is how I know.
Can you post your code or send me a copy in-world?
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
04-01-2006 13:19
From: Argent Stonecutter
Right. It's pretty rare that you need to take action when permissions are denied... all you need to do is know whether you have them or not.

If you're doing something where time is critical, you probably should have already requested the permissions you need, because you don't know how long that permission dialog will sit there on the user's screen. :)


Of course. I wasn't thinking about time-critical issues, but rather delayed failures. One example I can think of is something where certain permissions are required from the owner, and then a customer can come and interact with it. Say, a game which pays out winnings, so the owner needs to grant debit permissions. If the owner doesn't grant the permissions, the game won't work, and anyone who tries to play it will get an error message saying "Sorry, the owner hasn't set this up correctly", or the game won't respond to input at all, depending on how it's been written. But the owner's maybe under the impression that his game is set up and working, and he won't find out until later that it's not set up right.

The only way around this that I can think of (assuming one uses your design and ignores negatives in the run time permissions event) is to use a timer, and then nag the owner if the timer expires and the permissions haven't yet been received. Doable, but IMO it's a slightly better user interface/experience if the owner receives the error/warning message when he hits the No button, rather than a few seconds/minutes later.

It's a small niggle in my mind, that's all :)
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
04-01-2006 18:31
From: Karen Linden
We've worked hard to address many issues introduced in 1.9.0. We are working to resolve the following for our next release, 1.9.0(20), which will be released the week of April 3 (exact day not determined yet):

* Object is still animating me after standing up
* Second run_time_permissions event during llReleaseControls call
* Indicate when the agent will be able to log in again after logging out
* Dragging on an attachment moves cursor to unexpected spot
* Viewer crash when closing duplicate group IM session
According to Known Issues, how will they fix run_time_permissions's issue? It is recalling run_time_permissions when you stand up that annoys me. Will they get rid of second run_time_permissions? I'm afraid that they set it on purpose. :(
_____________________
:) Seagel Neville :)
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-01-2006 20:17
From: Ziggy Puff
Of course. I wasn't thinking about time-critical issues, but rather delayed failures.
In the example you gave you'd want to make sure that requesting debit permission was not the final step in setting the table up, so that a later operation could perform the test.

There's other failure modes in any setup that can produce this... for example clicking "Ignore" on a dialog. A "final_check()" routine that can't be bypassed is pretty important. A few decades back several people died because of a missed "final check" in a product called the "Therac 25". Google for it, it's instructive.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
04-02-2006 10:37
Wow.
Pericat Aquitaine
Registered User
Join date: 26 Feb 2006
Posts: 24
04-02-2006 12:34
From: Argent Stonecutter
Can you post your code or send me a copy in-world?


I'll try. I've not posted code before, so I may screw it up.

This is from the changed function if 'agent' is attached to the boat:

CODE


llRequestPermissions(agent, PERMISSION_TAKE_CONTROLS
| PERMISSION_TRIGGER_ANIMATION
| PERMISSION_CONTROL_CAMERA
| PERMISSION_TRACK_CAMERA);


(I don't think I need the track perm, but I've been a bit desperate of late.)

If 'agent' is null, however, this should execute:

CODE

llWhisper(0, "cleaning up now");

cleanupSails();

llSetStatus(STATUS_PHYSICS, FALSE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);


(I used to add 'llReleaseControls()', but with 'agent' being null, that never seemed to help.)

This is my entire run_time_permissions function:
CODE

run_time_permissions(integer permissions) {
if((permissions & PERMISSION_TAKE_CONTROLS) == PERMISSION_TAKE_CONTROLS) {
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_UP |
CONTROL_LEFT | CONTROL_RIGHT |
CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT,
TRUE, FALSE);

if((permissions & PERMISSION_TRIGGER_ANIMATION) == PERMISSION_TRIGGER_ANIMATION) {
llStopAnimation("sit");
llStartAnimation("stand");
} else {
llWhisper(0, "anim perms not set");
}

if((permissions & PERMISSION_CONTROL_CAMERA) == PERMISSION_CONTROL_CAMERA) {
if((permissions & PERMISSION_TRACK_CAMERA) == PERMISSION_TRACK_CAMERA) {
camera_init();
}
} else {
llWhisper(0, "cam perms not set");
}
} else {
llWhisper(0, "no control permissions; didn't try for anim or cam");
}
}


If I don't have permission to work the keyboard input, I don't bother trying to change either the animation or camera setting.

When I click the "Stand Up" or the "Release Controls" buttons, the boat comes back with:

CODE

pericat's sloop .97 whispers: cam perms not set
pericat's sloop .97 whispers: no control permissions; didn't try for anim or cam
pericat's sloop .97 whispers: cleaning up now


I also get these errors in the 'bad scripter' window:

CODE

pericat's sloop .97: Script trying to take controls from owner but PERMISSION_TAKE_CONTROLS permission not set!
pericat's sloop .97: Script trying to take controls from owner but PERMISSION_TAKE_CONTROLS permission not set!


To see if it was possible to do things right, I added this bit in the control function:
CODE

integer candoanim = FALSE;
integer candocontrols = FALSE;
integer candocam = FALSE;
integer candocamtrack = FALSE;

if((permissions & PERMISSION_TRIGGER_ANIMATION) == PERMISSION_TRIGGER_ANIMATION) {
candoanim = TRUE;
}
if ((permissions & PERMISSION_TAKE_CONTROLS) == PERMISSION_TAKE_CONTROLS) {
candocontrols = TRUE;
}
if ((permissions & PERMISSION_CONTROL_CAMERA) == PERMISSION_CONTROL_CAMERA) {
candocam = TRUE;
}

if ((permissions & PERMISSION_TRACK_CAMERA) == PERMISSION_TRACK_CAMERA) {
candocamtrack = TRUE;
}

if (keypress & CONTROL_UP) {
if(candoanim) {
llStopAnimation(currentanim);
llWhisper(0, "anim stopped");
}
cleanupSails();
llWhisper(0, "sails fore and aft");
llSetStatus(STATUS_PHYSICS, FALSE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);
llWhisper(0, "boat status reset");
if(candocam && candocamtrack) {
llClearCameraParams();
llWhisper(0, "camera params cleared");
llSetCameraParams([CAMERA_ACTIVE, 0]);
llWhisper(0, "camera inactive");
llReleaseCamera(agent);
llWhisper(0, "camera released");
}
if(candocontrols) {
llReleaseControls();
llWhisper(0, "controls released");
}
llUnSit(agent);
llWhisper(0, "elvis has left the building");


Now, if I use the CONTROL_UP key to delink, the boat chatters back:
CODE

pericat's sloop .97 whispers: anim stopped
pericat's sloop .97 whispers: sails fore and aft
pericat's sloop .97 whispers: boat status reset
pericat's sloop .97 whispers: camera params cleared
pericat's sloop .97 whispers: camera inactive
pericat's sloop .97 whispers: camera released
pericat's sloop .97 whispers: controls released
pericat's sloop .97 whispers: elvis has left the building
pericat's sloop .97 whispers: no control permissions; didn't try for anim or cam
pericat's sloop .97 whispers: no control permissions; didn't try for anim or cam
pericat's sloop .97 whispers: cleaning up now


No script errors reported. Note that someone's still going through run-time-perms twice before I get to run my cleanup bit in the changed function. The whispers are different, since I've made sure to release controls and camera and stop animations *before* I delink the avatar.

Lastly, if I remove the camera stuff from the original llRequestPermissions call:
CODE

llRequestPermissions(agent, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);


I have no errors reported at all with using the Stand Up or Release Controls buttons. There's still the double-call to run-time-perms:
CODE

pericat's sloop .97 whispers: cam perms not set
pericat's sloop .97 whispers: no control permissions; didn't try for anim or cam
pericat's sloop .97 whispers: cleaning up now


but no script window errors.

At this point, I think all I can do is wait for Wednesday's update and see where I stand afterward.
_____________________
I like ducks. They're just so... ducky.
Web Page
slow but steady
Join date: 4 Dec 2004
Posts: 129
04-02-2006 16:48
Pericat, You might try try adding llReleaseControls() at the top of the run_time_permissions event. Before even checking anything.

That would be in keeping with my findings, that apparently if you have controls you cant release control permissions...
Pericat Aquitaine
Registered User
Join date: 26 Feb 2006
Posts: 24
04-02-2006 21:37
That appears to give me errors right at the start. :( Nifty idea, though.
_____________________
I like ducks. They're just so... ducky.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-03-2006 06:40
From: Pericat Aquitaine
I'll try. I've not posted code before, so I may screw it up.

This is from the changed function if 'agent' is attached to the boat:

CODE


llRequestPermissions(agent, PERMISSION_TAKE_CONTROLS
| PERMISSION_TRIGGER_ANIMATION
| PERMISSION_CONTROL_CAMERA
| PERMISSION_TRACK_CAMERA);


Good so far.
From: someone
If 'agent' is null, however, this should execute:

CODE

llWhisper(0, "cleaning up now");

cleanupSails();

llSetStatus(STATUS_PHYSICS, FALSE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);
The overall change code should be something like this, right?
CODE

change(integer what)
{
if(what & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
if(agent)
request_permissions();
else if(have_started)
cleanup();
}
}


Then request_permissions looks like:
CODE

request_permissions()
{
integer needed_perms =
PERMISSION_TAKE_CONTROLS
| PERMISSION_TRIGGER_ANIMATION
| PERMISSION_CONTROL_CAMERA
| PERMISSION_TRACK_CAMERA;
if((llGetPermissions() & needed_perms) == needed_perms)
{
have_permissions = TRUE;
try_startup();
}
else if(agent)
{
llRequestPermissions(agent_ needed_perms);
}
}

From: someone

This is my entire run_time_permissions function:
CODE

run_time_permissions(integer permissions) {
if((permissions & PERMISSION_TAKE_CONTROLS) == PERMISSION_TAKE_CONTROLS) {
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_UP |
CONTROL_LEFT | CONTROL_RIGHT |
CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT,
TRUE, FALSE);

if((permissions & PERMISSION_TRIGGER_ANIMATION) == PERMISSION_TRIGGER_ANIMATION) {
llStopAnimation("sit");
llStartAnimation("stand");
} else {
llWhisper(0, "anim perms not set");
}

if((permissions & PERMISSION_CONTROL_CAMERA) == PERMISSION_CONTROL_CAMERA) {
if((permissions & PERMISSION_TRACK_CAMERA) == PERMISSION_TRACK_CAMERA) {
camera_init();
}
} else {
llWhisper(0, "cam perms not set");
}
} else {
llWhisper(0, "no control permissions; didn't try for anim or cam");
}
}

Way too complicated. You have four permissions you require, you might as well check them all at once:
CODE

run_time_permissions(integer perms)
{
integer needed_perms =
PERMISSION_TAKE_CONTROLS
| PERMISSION_TRIGGER_ANIMATION
| PERMISSION_CONTROL_CAMERA
| PERMISSION_TRACK_CAMERA;
if((perms & needed_perms) == needed_perms)
{
have_perms = TRUE;
try_startup();
}
}

Finally, in try_startup:
CODE

try_startup()
{
if(have_started) // Already done...
return;
if(!agent) // nobody's home, bail.
return;
if(!have_perms) // haven't got permissions yet
return;
// may be other checks for things you might need to have correct, none yet...
// ...
// At this point you know it's safe to proceed with ALL the initialization!
llSetStatus(STATUS_PHYSICS, TRUE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, TRUE);

llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_UP |
CONTROL_LEFT | CONTROL_RIGHT |
CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT,
TRUE, FALSE);

llStopAnimation("sit");
llStartAnimation("stand");

camera_init();

have_started = TRUE;
}

And finally...
CODE

cleanup()
{
if(!have_started) // Nothing to clean up, do't do anything.
return;

cleanupSails();

// llReleaseControls goes here as well

llSetStatus(STATUS_PHYSICS, FALSE);
llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);

have_started = FALSE;
}


Much simpler, yes? You have one startup routine, one cleanup routine, and you just keep trying the startup routine whenever there's a possibility you could be ready.
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
04-03-2006 06:53
Aha, Argent, thanks. I've got what to do from now on.
One question, should I set llAvatarOnSitTarget's key as a global variable?
_____________________
:) Seagel Neville :)
Ricky Shaftoe
Owner, "Rickymations"
Join date: 27 May 2005
Posts: 366
04-03-2006 08:47
As Seagal just pointed out to me in another thread, isn't this issue already on LL's "known issues" list? This from the current "known issues" thread:

From: someone
We've worked hard to address many issues introduced in 1.9.0. We are working to resolve the following for our next release, 1.9.0(20), which will be released the week of April 3 (exact day not determined yet):

* Object is still animating me after standing up


See /255/56/97687/1.html

I'm hoping I can just sit tight and see if this fix solves the problem. Can I?
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-03-2006 09:50
From: Seagel Neville
Aha, Argent, thanks. I've got what to do from now on.
One question, should I set llAvatarOnSitTarget's key as a global variable?
Yes, all the shared variables (agent, have_started, have_perms, etcetera) need to be global.

Ricky: Hopefully they'll get the fix right this time, but some of the changs in run_time_permissions should be staying.

You could try adding a timer event as a workaround in the meantime:
CODE

timer()
{
if(llAvatarOnSitTarget() != agent_being_animated)
if(llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation(...);
agent_being_animated = NULL_KEY;
}
}
Pericat Aquitaine
Registered User
Join date: 26 Feb 2006
Posts: 24
04-03-2006 13:26
From: Argent Stonecutter
Much simpler, yes? You have one startup routine, one cleanup routine, and you just keep trying the startup routine whenever there's a possibility you could be ready.


Ah, thanks, Argent! That got me back on the right track. It was getting just horridly complicated as I flailed about trying to sort out what was wrong.

You're a marvel! Much appreciated.
_____________________
I like ducks. They're just so... ducky.
Zuleica Sartre
Registered User
Join date: 27 Sep 2005
Posts: 105
04-03-2006 18:45
I was maintaining a script I didn't originally write when a similar issue came up.

It seemed that the script was stopping animations without animation permissions requested and prior to 1.9 this did not generate a permissions error.

I had to request animations permissions prior to stopping animations and the errors went away.
Ricky Shaftoe
Owner, "Rickymations"
Join date: 27 May 2005
Posts: 366
04-03-2006 19:30
From: someone
Ricky: Hopefully they'll get the fix right this time, but some of the changs in run_time_permissions should be staying.


So should I just sit tight until the fix arrives? The issue for me is that I've already got hundreds of customers using my now-borked scripts. Sure, I could write a workaround, but that means changing a hundred odd poseballs on my shop floor, and then trying to track down users to fix theirs as well.

It's incomprehensible to me that LL has broken this.
Web Page
slow but steady
Join date: 4 Dec 2004
Posts: 129
04-04-2006 08:35
From: Ricky Shaftoe
So should I just sit tight until the fix arrives? The issue for me is that I've already got hundreds of customers using my now-borked scripts. Sure, I could write a workaround, but that means changing a hundred odd poseballs on my shop floor, and then trying to track down users to fix theirs as well.

It's incomprehensible to me that LL has broken this.


Yep. Hang tight. Most of what we're doing here is an attempt to gain greater understanding of the system to assure this doesn't happen to future scripts. Not that it will really make a difference. A bug is a bug.

Incomprehensible? Not at all. Permissions is a pot that every cook at LL has added to. Need I say more?
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-04-2006 09:33
You may still need to fix the scripts to avoid error messages from sloppy but previously working code, but they'll fix the "hanging pose" problem.

You could also offer your customers an object with a "STOP ALL ANIMATIONS" script in it, as a freebie, which will endear them to you and allow them to work around the problem when they get stuck on other people's kit as well.
Web Page
slow but steady
Join date: 4 Dec 2004
Posts: 129
04-04-2006 10:29
CODE
	run_time_permissions( integer perm )
{
if (perm!=PERMISSION_TRIGGER_ANIMATION+PERMISSION_TAKE_CONTROLS && llAvatarOnSitTarget()!=NULL_KEY )
llRequestPermissions( kAv, PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );
else
{
llTakeControls( CONTROL_ROT_LEFT|CONTROL_ROT_RIGHT|CONTROL_LEFT|CONTROL_RIGHT,TRUE,FALSE);
}
}
This seems to be working for me in another situation. It makes sense too.
Web Page
slow but steady
Join date: 4 Dec 2004
Posts: 129
04-04-2006 10:42
My bad. But THIS does work:

CODE
 
run_time_permissions( integer perm )
{
if ( llAvatarOnSitTarget()!=NULL_KEY )
{
if ( perm != PERMISSION_TRIGGER_ANIMATION + PERMISSION_TAKE_CONTROLS )
llRequestPermissions( kAv, PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS );
else
{
llTakeControls( CONTROL_ROT_LEFT |CONTROL_ROT_RIGHT |CONTROL_LEFT |CONTROL_RIGHT, TRUE, FALSE);
// plus any other start up coding
}
}
}
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
04-04-2006 14:14
A coding style suggestion. :)
CODE

run_time_permissions( integer perm )
{
key kAv = llAvatarOnSitTarget();
if ( kAv != NULL_KEY )
{
integer iPerm =
PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS;
if( (perm & iPerm) != iPerm )
llRequestPermissions(kAv, iPerm)
else
{
//...
}
}
}
Why?

Because if you (for example) use this in a script where you're juggling other permissions as well, then perm may become perm | PERMISSION_DEBIT or something. So you want to mask out just the permissions you're interested in... and declaring them just one place makes it harder to mess them up.
Ricky Shaftoe
Owner, "Rickymations"
Join date: 27 May 2005
Posts: 366
04-04-2006 20:51
OK, I'm sitting tight. And yes, once I see the fix, I'll be happy to write code to clean up whatever I need to clean up. And yes, I have indeed offered my customers a free animation-stopper on my shop floor; that seems to have reduced the flow of complaints and questions. :)

*keeping fingers crossed*
1 2