Jump to content

No-Permissions Teleport!


LoneWolfiNTj
 Share

Recommended Posts

I have a skybox with an interesting feature: if you sit on the roof, you instantly end up standing on the floor of the skybox 25m below; and if you sit on the floor, you instantly end up standing on the roof; and no permissions are asked either way.

Until tonight, I had no clue how that was done, because the perms on the scripts in my skybox are "no modify" so I can't read the scripts. But tonight it hit me like a thunderbolt: It's being done using llSitTarget() trickery! On sitting, the person is translated by some <x,y,z> vector to a new location then unsat with llUnSit().

So I wondered if this is confined to a single region. No it is not! I created the following script:

// No-Permissions-Teleport.lsl
default
{
    state_entry()
    {
        llSitTarget(<1234.5, -2345.6, 0.0>, llEuler2Rot(<0.0, 0.0, PI>));
    }
    changed(integer what_changed)
    {
        if (what_changed & CHANGED_LINK)
        {
            key ava_key = llAvatarOnSitTarget();
            if (NULL_KEY != ava_key)
            {
                llUnSit(ava_key);
            }
        }
    }
}

Then I went to a sandbox, rezzed a slab 10m x 10m x 10cm, 100m in the air, flew up, stood on the slab, then sat on it. Boom, I was in a different region altogether! Unbelievable! Check out the attached image; the red circle is where I started, and the "you are here" icon is where I ended up.

So, one can do no-permissions teleporting this way. I'm not sure what the limitations are, or if there are any. I'm tempted to try translations of 100km just to see if it actually works. If it can transport me 2 regions away (as it did), I'm pretty sure it can transport me anywhere in SL. I'll experiment with that.

No-Permissions-Teleport.png

  • Like 1
Link to comment
Share on other sites

Interesting. Sit Target teleporters have been around for ages and they certainly do work across region borders, but I'm surprised they've changed since the wiki recorded back in 2009:

Quote
  • offset is limited to 300.0 meters on each axis. The x, y and z components must be in the range [-300, 300.0][2].
    • If they are outside the acceptable range they are rounded to the closest limit.

 

  • Like 2
Link to comment
Share on other sites

21 minutes ago, Mollymews said:

have a look at llSitTarget

http://wiki.secondlife.com/wiki/LlSitTarget

which says that the range is 300.0 on each axis. So yes it is possible to go 2 regions over depending on the distance of the seat from the region border

if you are able to go more than 300 in some circumstance then you have found a bug (undocumented feature)

Ah-ha. That explains why my transport was at about a 45° angle instead of the roughly 60° angle one would expect. I had no idea of the actual region size until a minute ago when I got curious and googled "Second Life region size" and got "256×256 meters". So it appears that my vector <1234.5, -2345.6, 0.0> got rounded to <300.0, -300.0, 0.0>. So this is local only.

Still, it's useful for short-distance stuff like within a parcel, or between floor and roof of a skybox. (Though, I don't see how to enforce privacy, as llSitTarget doesn't discriminate between avatars, and by the time the "changed" event occurs, the unwanted avatar is already in side your skybox. Which is one of the reasons why I eventually replaced the floor and roof of my skybox with slabs of my own design, then added a security orb and modified the hell out of it.)

  • Like 1
Link to comment
Share on other sites

20 minutes ago, LoneWolfiNTj said:

 I don't see how to enforce privacy, as llSitTarget doesn't discriminate between avatars, and by the time the "changed" event occurs, the unwanted avatar is already in side your skybox

 a way to modify your code snippet to deal with unwanted avatars

changed(integer what_changed)
{
   if (what_changed & CHANGED_LINK)
   {
      key ava_key = llAvatarOnSitTarget();
      if (NULL_KEY != ava_key)
      {
         if (AvatarIsOK(ava_key))  // AvatarIsOK is some user defined function to determine ok from not ok
     {
            llUnSit(ava_key);  // ok
         }
         else
         {
            llEjectFromLand(ava_key); // not ok
         }
      }
   }
}

 

  • Like 1
Link to comment
Share on other sites

FYI, an avatar that is sitting on an object can be moved up to 2000 meters away from the root using functions like llSetLinkPrimitiveParamsFast and PRIM_POS_LOCAL.

llUnsit doesn't require any permissions either. All it requires is:

  1. The agent is sitting on the scripted object, or
  2. The agent is over land owned by the scripted object's owner and/or a group the owner has land rights for.
Edited by Wulfie Reanimator
  • Like 1
Link to comment
Share on other sites

9 hours ago, LoneWolfiNTj said:

I have a skybox with an interesting feature: if you sit on the roof, you instantly end up standing on the floor of the skybox 25m below; and if you sit on the floor, you instantly end up standing on the roof; and no permissions are asked either way.

Until tonight, I had no clue how that was done, because the perms on the scripts in my skybox are "no modify" so I can't read the scripts. But tonight it hit me like a thunderbolt: It's being done using llSitTarget() trickery! On sitting, the person is translated by some <x,y,z> vector to a new location then unsat with llUnSit().

So I wondered if this is confined to a single region. No it is not! I created the following script:

// No-Permissions-Teleport.lsl
default
{
    state_entry()
    {
        llSitTarget(<1234.5, -2345.6, 0.0>, llEuler2Rot(<0.0, 0.0, PI>));
    }
    changed(integer what_changed)
    {
        if (what_changed & CHANGED_LINK)
        {
            key ava_key = llAvatarOnSitTarget();
            if (NULL_KEY != ava_key)
            {
                llUnSit(ava_key);
            }
        }
    }
}

Then I went to a sandbox, rezzed a slab 10m x 10m x 10cm, 100m in the air, flew up, stood on the slab, then sat on it. Boom, I was in a different region altogether! Unbelievable! Check out the attached image; the red circle is where I started, and the "you are here" icon is where I ended up.

So, one can do no-permissions teleporting this way. I'm not sure what the limitations are, or if there are any. I'm tempted to try translations of 100km just to see if it actually works. If it can transport me 2 regions away (as it did), I'm pretty sure it can transport me anywhere in SL. I'll experiment with that.

No-Permissions-Teleport.png

Not to be a downer, but you discovered something that some people have been using for years. 😉

 

4 hours ago, Wulfie Reanimator said:

FYI, an avatar that is sitting on an object can be moved up to 2000 meters away from the root using functions like llSetLinkPrimitiveParamsFast and PRIM_POS_LOCAL.

*1000 (you made me check that again to see if LL changed anything recently, but they didn't)

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

moving an avatar by the link method is my preferred option

like my bed.  If SomeRandom Person sits on my bed then I move them outside my house and unsit them. Which is a long fall when bed is in a skybox

i did a mod of this when I had a Linden Home.  If anyone climbed into my bed then move them out onto the public road and unsit

another mod was, move the person outside into the garden where they get their feet pecked by baby chickens. Chickens are physical and go to the feet of avatar and give a little bump, just enough to jiggle their avatar, making ebil noises like: CHEEP! CHEEP! YOU CHEEP! KEHEHEHE!!!

and when the person goes aha! and Sit Ground. Then baby chickens climb on them and go AWWW! I LUV U !! U TE BEST!!! CHEEP!! CHEEP!!

baby chickens can be really annoying 😸

  • Like 2
  • Haha 3
Link to comment
Share on other sites

13 hours ago, LoneWolfiNTj said:

tonight it hit me like a thunderbolt

i like your OP because you had a lightbulb moment. This is the joy of learning.  When the lightbulb goes bing! is really satisfying. So can share as many lightbulb moments as you want and I will like them all

 

  • Like 2
Link to comment
Share on other sites

On 9/23/2021 at 2:07 AM, Mollymews said:

 ...a way to modify your code snippet to deal with unwanted avatars...

Ah-ha! I didn't think of that, but yes, one could always eject a person from one's parcel (or TP them home if one wants to be really annoying) instead of just llUnSit'ing them.

The AvatarIsOk() function could be just seeing if llGetOwner == ava_key, or I could read a "whitelist" notecard on default state_entry and see if ava_key is either me, or on my whitelist. No dialog or text boxes needed that way, though I'd have to copy a mess of notecard-reading code from another script and run it on state_entry and on_rez. Then have AvatarIsOk() be something like:

integer AvatarIsOk(key ava_key)
{
   if (ava_key == llGetOwner()) {return TRUE;}
   for (integer i ; i < llGetListLength(whitelist) ; ++i)
   {
      if (ava_key == llList2String(whitelist, i)) {return TRUE;}
   }
   return FALSE;
}

That's untested so probably buggy but should be going in the right direction, no?

  • Like 1
Link to comment
Share on other sites

14 minutes ago, LoneWolfiNTj said:

notecard-reading

I never really read notecards for personal-use projects. it's so much easier to just have a list of keys (or names) in the script:

list whitelist = 
[  "quistess alpha", // all lower case.
   "mollymews resident",
   "lonewolfintj resident"
];

// ... //

if(~llListFindList(whitelist,[llToLower(llKey2Name(UUID))]))
{  // person is on the list.
}

 

Edited by Quistess Alpha
  • Like 2
Link to comment
Share on other sites

12 minutes ago, Quistess Alpha said:

it's so much easier to just have a list of keys (or names) in the script

Ah, "hard-coding". Yep, that's one of several ways to do that. (Another way is to have the user enter the info via text box, but the info goes "poof" every time the script is edited. Or one can use notecards. And maybe other ways I'm unaware of.)

I like the notecard approach from the usage standpoint, though, in that it's easier to edit a notecard than a script (though the code to read notecards is really messy).

And, I'm becoming wary of thinking of stuff I create (objects, scripts) as being "just for my own use", as I keep changing my mind and saying "y'know, this here xxxxx is kinda cool and I think others may like it, so I think I'll upload it to SL Marketplace and sell it for L$50". Then I have to make it more "user-friendly" instead of "hard-coded". So I've been thinking along the lines of "could a non-scripting SL resident easily use this?" lately even for stuff I'm currently making only for myself.

I like your list-lookup approach, though:

if(~llListFindList(whitelist,[llToLower(llKey2Name(UUID))]))

That's quite a bit better than my clunky for-loop approach. And I realize now my untested code wouldn't have worked because the whitelist is going to be names but ava_key is going to be type "key", so I'd need to get the name from ava_key before comparing to the list.

Link to comment
Share on other sites

21 minutes ago, Quistess Alpha said:

I never really read notecards for personal-use projects. it's so much easier to just have a list of keys (or names) in the script:

I agree.  The best argument in favor of notecard entry is that notecards are portable and can be edited/copied externally with little trouble.  A scripter can then set no-mod perms on the script itself and still let the user update the access whitelist easily.  For my personal use, where that's not a concern, I always simply hard-code whitelists into my scripts.

Having said that, you can still have updatable whitelists without using notecards if you are willing to do the extra work of writing routines to let the user add/remove whitelist names that he types into llTextBox entries.  It's fairly easy to write those routines.

  • Like 1
Link to comment
Share on other sites

11 minutes ago, Rolig Loon said:

Having said that, you can still have updatable whitelists without using notecards if you are willing to do the extra work of writing routines to let the user add/remove whitelist names that he types into llTextBox entries.  It's fairly easy to write those routines.

Oh I agree, neither method is particularly /hard/ although it can be a bit tedious, and you need to be a tad careful that it fits together with the actual thing your script is supposed to be doing.

There are advantages and disadvantages for notecards vs textboxes, but it seems to me like notecards add a lot of implicit usability features that would be more tedious to do with textboxes (easily list who's on the whitelist by editing the notecard, remove someone from anywhere in the list etc.) OTOH with textboxes/dialog, easier to (for example) present a list of nearby people, although you could just do that even if you had it notecard based..  .

Link to comment
Share on other sites

This is a hastily-written example of the sort of thing you could write to create a dynamic whitelisting system that does not involve notecard entry.  Names are simply added or removed through text box entries.  In practice, you'd probably want to add various safeguards, friendly messages, etc:

integer iChan;
integer iLsn;
integer iModList = -1;
key kValidate;
key kAv;
string strNameToUse;
list lEveryone;

default
{
    touch_end(integer num)
    {
        kAv = llDetectedKey(0);
        iChan = -1 * (integer)llFrand(100000.0);
        iLsn = llListen(iChan,"","","");
        llDialog( kAv, "Add or remove a name", ["Add", "Remove"], iChan);
        llSetTimerEvent(60.0);    //For timeout
    }

    listen( integer channel, string name, key id, string message)
    {
        integer i = llListFindList(["Add","Remove"],[message]);
        if (~i)
        {
            iModList = i;
            llTextBox(kAv, "Type the username of the person you want to add to or remove from the access list", iChan);
        }
        else    // Message must be an entry from a text box
        {
            strNameToUse = llToLower(message);
            kValidate = llRequestUserKey(strNameToUse);
        }
    }

    dataserver( key id, string data)
    {
        if ( kValidate == id )
        {
            if ( (key)data == NULL_KEY)
            {
                llRegionSayTo( kAv, 0, "You have not typed a valid username.");
            }
            else if ( ~iModList )   
            {
                integer idx = llListFindList( lEveryone, [strNameToUse] );
                if( idx == -1)
                {
                    if (iModList == 0)    //Adding a name
                    {
                        lEveryone += [strNameToUse];
                    }
                    else    //Trying to remove a name
                    {
                        llRegionSayTo(kAv, 0, strNameToUse +" is not on your access list");
                    }
                }
                else
                {
                    if( iModList == 1 )    //Removing a name
                    {
                        lEveryone = llDeleteSubList( lEveryone, idx, idx );
                    }
                    else
                    {
                        llRegionSayTo(kAv,0, strNameToUse + " is already on your access list");
                    }
                }
                llSetTimerEvent(0.0);
                llListenRemove(iLsn);
                iModList = -1;
                llRegionSayTo(kAv,0, "Your access list is: \n" + llDumpList2String(lEveryone,"\n"));
            }
        }
    }

    timer()
    {
        llSetTimerEvent(0.0);
        llListenRemove(iLsn);
        iModList = -1;
    }
}

        The usual caveat applies:  This script is not tested fully.  It compiles but I make no guarantee that I haven't left out something important or failed to notice an accidental pothole.  And, of course, this is just for creating/modifying the access list.  You'd need to connect it to whatever code you write to USE the whitelist.  :)

 

                

          

Edited by Rolig Loon
Additional information
  • Like 2
Link to comment
Share on other sites

6 hours ago, LoneWolfiNTj said:

I like the notecard approach from the usage standpoint, though, in that it's easier to edit a notecard than a script

when we start getting into providing products commercially then it brings in a whole other level which we don't usually fuss too much about when we write scripts just for ourselves

a way to do notecards is to allow our product users to go both ways. They can add/remove people  with a textbox and edit the notecard if they want

in this case then a way is to provide a Operations dialog which has a Load button and a Print button

the Load button will load/read the notecard

the Print button will print/say the usernames in the access list using llRegionSayTo from where the text can be copypasted into the notecard

is sometimes plainer to use states to do this. Pcode example:
 

default
{
  ... OnScriptReset or OnLoad
      read notecard line for username
      validate llRequestUserKey(username). Add username to access list

  ... OnFinish reading goto
      state main;
}  

state print
{
    ... loop thru the access global list
    ... print/say username. llRegionSayTo(...)

    ... OnFinish printing
        state main;
}

state main
{
    ... discover avatar presence. llSensor(...) or llGetAgentList(...)
        get username. llDetectedName(...) or llName2Key(...). Allow/disallow activity per access list

    ... provide Operations llDialog(...) Add, Remove, Load, Print, ... etc
    
    ... OnAdd
        provide llTextbox(...) input username
        validate llRequestUserKey(username). Add username to access list
    ... OnRemove
        provide llTextbox(...) input username
        if name on access list, remove username
    ... OnLoad
        state default;  
    ... OnPrint
        state print;
}

 

Link to comment
Share on other sites

10 hours ago, Rolig Loon said:
list lEveryone;

That's similar to how my security orb (by "Manor House", but heavily-modified by me) handles whitelisting. The downside of that is, it's very "volatile": if the script is recompiled, or reset, or I "take" and re-rez the orb, the whitelist goes "poof".

Whereas, notecards are stored as disk files on Second Life server mainframes, so they're persistent. PC crashes? They come back. Region crashes? They come back. I have notecards in my inventory going back to 2013 when I first got into Second Life.

That's why I'm considering modifying my security orb still further, removing the the "Whitelist" button on the menu and pulling-in the whitelist from a notecard called "Whitelist" instead.

Which brings up the question of how my house works. It has a whitelist of people allowed to open the doors, but there's no notecard in its Contents. It has 56 prims, most with their own scripts, but the scripts are all no-mod so unreadable, so I don't know what it's doing. It must have some other way of storing data in a non-volatile way.

 

Link to comment
Share on other sites

The most obvious way around the volatile storage issue is to save the whitelist in a KVP key, for which you would need to own or have access to an Experience that is active on the region where your house is.  Failing that, you could send the list out of SL and store it in a remote server or in a Google sheet or similar medium.  Or, of course, if the whitelist is reasonably short you could parse its contents out to the Description fields of various links in the house.  My personal preference would be for KVP.

Link to comment
Share on other sites

4 hours ago, LoneWolfiNTj said:

Which brings up the question of how my house works. It has a whitelist of people allowed to open the doors, but there's no notecard in its Contents. It has 56 prims, most with their own scripts, but the scripts are all no-mod so unreadable, so I don't know what it's doing. It must have some other way of storing data in a non-volatile way.

 

check the Object Description fields of the prims.  See if there is anything in them

with key packing (9 chars per key) then can stuff 14 keys into a prim's Object Description (127 / 9 = 14).  56 prims * 14 keys = 784 avatars on a persistent whitelist

 

ps. can stuff another 28 into PRIM_TEXT as well (alpha'd so is not visible).  Which is another 1,568.  For 2,352 in total for that 56 prim building

Edited by Mollymews
  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...