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:
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: 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: 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: 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: 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: 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: 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: 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: 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:
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: 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? change(integer what) { if(what & CHANGED_LINK) { key agent = llAvatarOnSitTarget(); if(agent) request_permissions(); else if(have_started) cleanup(); } }
Then request_permissions looks like: 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: 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: 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: 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... 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.htmlI'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: 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
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: 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.  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*
|